Как обрезать строку при преобразовании в байты в C #? - PullRequest
9 голосов
/ 29 августа 2008

Я хотел бы поместить строку в байтовый массив, но строка может быть слишком большой, чтобы уместиться. В случае, если он слишком велик, я бы хотел поместить как можно больше строки в массив. Есть ли эффективный способ узнать, сколько символов поместится?

Ответы [ 5 ]

5 голосов
/ 29 августа 2008

Чтобы обрезать строку до байтового массива UTF8 без разделения на середину символа, я использую это:

static string Truncate(string s, int maxLength) {
    if (Encoding.UTF8.GetByteCount(s) <= maxLength)
        return s;
    var cs = s.ToCharArray();
    int length = 0;
    int i = 0;
    while (i < cs.Length){
        int charSize = 1;
        if (i < (cs.Length - 1) && char.IsSurrogate(cs[i]))
            charSize = 2;
        int byteSize = Encoding.UTF8.GetByteCount(cs, i, charSize);
        if ((byteSize + length) <= maxLength){
            i = i + charSize;
            length += byteSize;
        }
        else
            break;
    }
    return s.Substring(0, i);
}

Затем возвращаемая строка может быть безопасно передана в байтовый массив длины maxLength.

2 голосов
/ 29 августа 2008

Вы должны использовать класс Encoding для правильного преобразования в байтовый массив? Все объекты кодирования имеют переопределенный метод GetMaxCharCount, который даст вам «Максимальное количество символов, получаемых при декодировании указанного количества байтов». Вы должны быть в состоянии использовать это значение для обрезки вашей строки и правильного ее кодирования.

1 голос
/ 29 августа 2008

Куки, твой код не делает того, о чем ты думаешь. Предварительное выделение байтового буфера в вашем случае является пустой тратой, потому что он не будет использоваться. Скорее, ваше назначение удаляет выделенную память и сбрасывает ссылку arr, чтобы указать на другой буфер, потому что Encoding.GetBytes возвращает новый массив.

1 голос
/ 29 августа 2008

Класс кодирования в .NET имеет метод с именем GetByteCount, который может принимать строку или символ []. Если вы передадите 1 символ, он скажет вам, сколько байтов необходимо для этого 1 символа в любой кодировке, которую вы используете.

Метод GetMaxByteCount работает быстрее, но он выполняет вычисление в худшем случае, которое может вернуть большее число, чем фактически необходимо.

1 голос
/ 29 августа 2008

Эффективным способом было бы найти, сколько (пессимистически) байтов вам понадобится на символ с

Encoding.GetMaxByteCount(1);

затем делим размер строки на результат, затем конвертируем столько символов с помощью

public virtual int Encoding.GetBytes (
 string s,
 int charIndex,
 int charCount,
 byte[] bytes,
 int byteIndex
)

Если вы хотите использовать меньше памяти, используйте

Encoding.GetByteCount(string);

но это гораздо более медленный метод.

...