Diferença por escrito matriz de char seqüência vs. com System.IO.BinaryWriter
-
06-07-2019 - |
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?
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
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.