2013-11-08 2 views
0

Мне нужно ограничить вывод byte[] длиной, закодированной кодировкой UTF-8. Например. byte[] длина должна быть меньше или равна 1000 Сначала я написал следующий кодОграничить длину кодированных байтов UTF-8 из строки

  int maxValue = 1000; 

      if (text.Length > maxValue) 
       text = text.Substring(0, maxValue); 
      var textInBytes = Encoding.UTF8.GetBytes(text); 

работает хорошо, если строка только с помощью ASCII-символов, потому что 1 байт на символ. Но если символы выходят за рамки этого, это может быть 2 или 3 или даже 6 байтов на символ. Это будет проблемой с вышеуказанным кодом. Поэтому, чтобы исправить эту проблему, я написал это.

  List<byte> textInBytesList = new List<byte>(); 
      char[] textInChars = text.ToCharArray(); 
      for (int a = 0; a < textInChars.Length; a++) 
      { 
       byte[] valueInBytes = Encoding.UTF8.GetBytes(textInChars, a, 1); 
       if ((textInBytesList.Count + valueInBytes.Length) > maxValue) 
        break; 

       textInBytesList.AddRange(valueInBytes); 
      } 

Я не тестировал код, но я уверен, что он будет работать, как я хочу. Однако мне не нравится, как это делается, есть ли лучший способ сделать это? Что-то мне не хватает? или не знаете?

спасибо.

ответ

1

Моя первая публикация на переполнение стека, так что будьте нежны! Этот метод должен заботиться о вещах довольно быстро для вас ..

public static byte[] GetBytes(string text, int maxArraySize, Encoding encoding) { 
     if (string.IsNullOrEmpty(text)) return null;    

     int tail = Math.Min(text.Length, maxArraySize); 
     int size = encoding.GetByteCount(text.Substring(0, tail)); 
     while (tail >= 0 && size > maxArraySize) { 
      size -= encoding.GetByteCount(text.Substring(tail - 1, 1)); 
      --tail; 
     } 

     return encoding.GetBytes(text.Substring(0, tail)); 
    } 

Это похоже на то, что вы делаете, но без дополнительных накладных расходов из списка или того, чтобы считать с начала строки каждый раз. Я начинаю с другого конца строки, и, конечно же, предполагается, что все символы должны быть как минимум одним байтом. Поэтому нет смысла начинать итерацию вниз по строке, чем дальше, чем maxArraySize (или общая длина строки).

Затем вы можете вызвать метод, как так ..

 byte[] bytes = GetBytes(text, 1000, Encoding.UTF8); 
+0

Хорошо один, но его что-то, что я сделал, за исключением, может быть, производительность будет лучше. – xmen

Смежные вопросы