2008-08-29 14 views
8

Me gustaría poner una cadena en una matriz de bytes, pero la cadena puede ser demasiado grande para caber. En el caso de que sea demasiado grande, me gustaría poner la mayor cantidad de cadena posible en la matriz. ¿Hay una manera eficiente de averiguar cuántos caracteres encajarán?¿Cómo trunco ​​una cadena al convertir a bytes en C#?

Respuesta

5

Con el fin de truncar una cadena a una matriz de bytes UTF-8 sin división en medio de un personaje que use este:

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); 
} 

La cadena devuelta luego se pueden transferir de forma segura a una matriz de bytes de longitud maxLength.

2

¿Debería utilizar la clase de codificación para hacer la conversión correcta a la matriz de bytes? Todos los objetos de codificación tienen un método reemplazado GetMaxCharCount, que le dará "la cantidad máxima de caracteres producida decodificando el número de bytes especificado". Debería poder usar este valor para recortar su cadena y codificarla adecuadamente.

+0

Esto no funciona si su límite es la cantidad de bytes. (Solo si el límite es la cantidad de caracteres) – roim

1

manera eficiente sería encontrar la cantidad (pesimista) bytes necesitará por carácter con

Encoding.GetMaxByteCount(1); 

luego dividiendo el tamaño de la cadena por el resultado, convirtiendo después que mucho caracteres con

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

Si desea utilizar menos memoria, use

Encoding.GetByteCount(string); 

pero eso es un método mucho más lento.

1

La clase de codificación en .NET tiene un método llamado GetByteCount que puede tomar una cadena o char []. Si pasa en 1 carácter, le dirá cuántos bytes se necesitan para ese 1 carácter en la codificación que esté utilizando.

El método GetMaxByteCount es más rápido, pero realiza un cálculo de caso más desfavorable que podría devolver un número mayor que el realmente necesario.

1

Cookey, su código no hace lo que aparentemente piensa que hace. La asignación previa del búfer de bytes en su caso es pura pérdida porque no se usará. Por el contrario, su asignación descarta la memoria asignada y restablece la referencia arr para apuntar a otro almacenamiento intermedio porque Encoding.GetBytes devuelve una nueva matriz.

Cuestiones relacionadas