Pergunta

Eu estou escrevendo texto para um arquivo binário em C # e ver a diferença na quantidade escrito entre escrever uma corda e uma matriz de caracteres. Estou usando System.IO.BinaryWriter e assistindo BinaryWriter.BaseStream.Length como ocorrem as gravações. Estes são os meus 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());
}

Eu não entendo por que a sobrecarga corda escreve 4 bytes quando estou escrevendo apenas 3 caracteres ASCII. Alguém pode explicar isso?

Foi útil?

Solução

A documentação para BinaryWriter.Write(string) estados que escreve um comprimento-prefixo string para este fluxo. A sobrecarga para Write(char[]) não tem esse prefixo.

Parece-me que os dados extra é o comprimento.

EDIT:

Apenas para ser um pouco mais explícito, use refletor. Você vai ver que ele tem este pedaço de código lá como parte do método Write(string):

this.Write7BitEncodedInt(byteCount);

É uma maneira de codificar um número inteiro utilizando o menor número possível de bytes. Para seqüências curtas (que usaríamos dia a dia que são menos de 128 caracteres), ele pode ser representado usando um byte. Para cadeias mais longas, ele começa a usar mais bytes.

Aqui está o código para essa função apenas no caso de você estiver interessado:

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

Após prefixar o comprimento utilizando esta codificação, ele grava os bytes para os caracteres na codificação desejada.

Outras dicas

A partir do BinaryWriter.Write(string) docs :

Grava um comprimento-prefixada corda para esta corrente na codificação corrente do BinaryWriter, e avança a posição corrente do fluxo de acordo com a codificação usada e os caracteres específicos a ser escrito para o fluxo de .

Este comportamento é provavelmente por isso que ao ler a parte de trás do arquivo no uso de uma BinaryReader a corda pode ser identificado. (Por exemplo 3Foo3Bar6Foobar pode ser analisado para a string "Foo", "Bar" e "Foobar", mas FooBarFoobar não podia ser.) Na verdade, usos BinaryReader.ReadString exatamente esta informação para ler um string de um arquivo binário.

A partir do BinaryWriter.Write(char[]) docs :

Grava uma matriz de caracteres para o fluxo de corrente e avança a posição corrente do fluxo de acordo com a codificação usada e os caracteres específicos a ser escrito para o fluxo.

É difícil exagerar como abrangentes e úteis a documentação no MSDN são. Sempre verifique-los primeiro.

Como já foi dito, BinaryWriter.Write (String) escreve o comprimento da corda para o fluxo, antes de escrever a seqüência em si.

Isso permite que o BinaryReader.ReadString () para saber quanto tempo a corda é.

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

Você quis olhar para o que foi realmente escrito? Eu acho que um terminador nulo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top