Diferencia en la escritura de cadenas frente a matriz de caracteres con System.IO.BinaryWriter

StackOverflow https://stackoverflow.com/questions/1014727

Pregunta

Estoy escribiendo texto en un archivo binario en C # y veo una diferencia en la cantidad escrita entre escribir una cadena y una matriz de caracteres. Estoy usando System.IO.BinaryWriter y viendo BinaryWriter.BaseStream.Length a medida que ocurren las escrituras. Estos son mis resultados:

using(BinaryWriter bw = new BinaryWriter(File.Open(“data.dat”), Encoding.ASCII))
{
  string value = “Foo”;

  // Writes 4 bytes
  bw.Write(value);

  // Writes 3 bytes 
  bw.Write(value.ToCharArray());
}

No entiendo por qué la sobrecarga de la cadena escribe 4 bytes cuando estoy escribiendo solo 3 caracteres ASCII. ¿Alguien puede explicar esto?

¿Fue útil?

Solución

La documentación para BinaryWriter.Write (string) indica que escribe una cadena con el prefijo de longitud en esta secuencia. La sobrecarga de Write (char []) no tiene ese prefijo.

Me parece que los datos adicionales son la longitud.

EDITAR:

Solo para ser un poco más explícito, usa Reflector. Verá que tiene este código allí como parte del método Write (string) :

this.Write7BitEncodedInt(byteCount);

Es una forma de codificar un número entero utilizando el menor número posible de bytes. Para cadenas cortas (que usaríamos día a día con menos de 128 caracteres), se puede representar con un byte. Para cadenas más largas, comienza a usar más bytes.

Aquí está el código para esa función en caso de que esté interesado:

protected void Write7BitEncodedInt(int value)
{
    uint num = (uint) value;
    while (num >= 0x80)
    {
        this.Write((byte) (num | 0x80));
        num = num >> 7;
    }
    this.Write((byte) num);
}

Después de prefijar la longitud usando esta codificación, escribe los bytes para los caracteres en la codificación deseada.

Otros consejos

Del BinaryWriter.Write (string) documentos :

Escribe una cadena con prefijo de longitud en esta secuencia en la codificación actual de BinaryWriter, y avanza la posición actual de la secuencia de acuerdo con la codificación utilizada y los caracteres específicos que se escriben en la secuencia .

Este comportamiento es probablemente así que cuando se vuelve a leer el archivo usando un BinaryReader , se puede identificar la cadena. (p. ej., 3Foo3Bar6Foobar se puede analizar en la cadena " Foo " ;, " Bar " y " Foobar " pero FooBarFoobar no podría ser.) De hecho, BinaryReader.ReadString usa exactamente esta información para leer una cadena de un archivo binario.

Del BinaryWriter.Write (char []) documentos :

Escribe una matriz de caracteres en la secuencia actual y avanza la posición actual de la secuencia de acuerdo con la codificación utilizada y los caracteres específicos que se escriben en la secuencia.

Es difícil exagerar cuán completos y útiles son los documentos en MSDN. Siempre verifíquelos primero.

Como ya se dijo, BinaryWriter.Write (String) escribe la longitud de la cadena en la secuencia, antes de escribir la cadena misma.

Esto permite que BinaryReader.ReadString () sepa cuánto dura la cadena.

using (BinaryReader br = new BinaryReader(File.OpenRead("data.dat")))
{
    string foo1 = br.ReadString();
    char[] foo2 = br.ReadChars(3);
}

¿Viste lo que realmente estaba escrito? Supongo que un terminador nulo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top