Differenza nella scrittura di stringhe rispetto a array di caratteri con System.IO.BinaryWriter

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

Domanda

Sto scrivendo testo in un file binario in C # e vedo una differenza di quantità scritta tra scrivere una stringa e un array di caratteri. Sto usando System.IO.BinaryWriter e guardando BinaryWriter.BaseStream.Length mentre avvengono le scritture. Questi sono i miei risultati:

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

Non capisco perché il sovraccarico della stringa scriva 4 byte quando scrivo solo 3 caratteri ASCII. Qualcuno può spiegare questo?

È stato utile?

Soluzione

La documentazione per BinaryWriter.Write (string) afferma che scrive una stringa con prefisso di lunghezza in questo flusso. Il sovraccarico di Write (char []) non ha tale prefisso.

Mi sembra che i dati extra siano la lunghezza.

EDIT:

Solo per essere un po 'più esplicito, usa Reflector. Vedrai che contiene questa parte di codice come parte del metodo Write (string) :

this.Write7BitEncodedInt(byteCount);

È un modo per codificare un numero intero usando il minor numero possibile di byte. Per stringhe brevi (che utilizzeremmo giorno per giorno con meno di 128 caratteri), può essere rappresentato utilizzando un byte. Per stringhe più lunghe, inizia a utilizzare più byte.

Ecco il codice per quella funzione nel caso in cui tu sia interessato:

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

Dopo aver prefissato la lunghezza usando questa codifica, scrive i byte per i caratteri nella codifica desiderata.

Altri suggerimenti

Dal BinaryWriter.Write (stringa) docs :

Scrive una stringa con prefisso di lunghezza su questo flusso nella codifica corrente di BinaryWriter e fa avanzare la posizione corrente del flusso in conformità con la codifica utilizzata e i caratteri specifici che vengono scritti nel flusso .

Questo comportamento è probabilmente tale che durante la lettura del file utilizzando un BinaryReader è possibile identificare la stringa. (ad es. 3Foo3Bar6Foobar può essere analizzato nella stringa " Foo " ;, " Bar " e " Foobar " ma FooBarFoobar non potrebbe essere.) In realtà, BinaryReader.ReadString utilizza esattamente queste informazioni per leggere una stringa da un file binario.

Dal BinaryWriter.Write (char []) docs :

Scrive una matrice di caratteri nello stream corrente e fa avanzare la posizione corrente dello stream in conformità con la codifica utilizzata e i caratteri specifici che vengono scritti nello stream.

È difficile sopravvalutare la completezza e l'utilità dei documenti su MSDN. Controllali sempre per primi.

Come già detto, BinaryWriter.Write (String) scrive la lunghezza della stringa nello stream, prima di scrivere la stringa stessa.

Ciò consente a BinaryReader.ReadString () di sapere quanto è lunga la stringa.

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

Hai visto cosa è stato effettivamente scritto? Immagino un terminatore null.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top