Perché BinaryWriter anteporre incomprensibile per l'inizio di un corso d'acqua? Come si fa a evitarlo?

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

Domanda

Ho il debug alcuni problemi con la scrittura pezzi di un oggetto in un file e ho ottenuto fino al caso base di appena l'apertura del file e la scrittura di "TEST" in esso. Sto facendo questo da qualcosa come:

static FileStream fs;
static BinaryWriter w;
fs = new FileStream(filename, FileMode.Create);
w = new BinaryWriter(fs);

w.Write("test");

w.Close();
fs.Close();

Purtroppo, questo finisce per anteponendo una scatola per la parte anteriore del file e sembra in questo modo:

TEST, con una scatola di divertimento sulla parte anteriore. Perché è questo, e come posso evitarlo?

Edit: non sembra essere la visualizzazione della casella di qui, ma è il carattere Unicode che sembra senza senso

.
È stato utile?

Soluzione

Non sono marchi di byte-ordine, ma una lunghezza di prefisso, in base alle MSDN :

public virtual void Write(string value);
  

Scrive una stringa di lunghezza prefissata a   [La] flusso

e sarà necessario che la lunghezza prefisso se vi capitasse di voler leggere la stringa indietro da quel punto. Vedere BinaryReader.ReadString() .

Ulteriori

Poiché sembra si vuole realmente un correttore di file-intestazione

  1. E 'un problema? Hai letto la lunghezza del prefisso indietro in modo come un tipo di controllo sul file funziona OK

  2. È possibile convertire la stringa in un byte [] array, probabilmente utilizzando Encoding.ASCII. Ma gallina si deve usare sia ad un (implicita) di lunghezza fissa o ... prefisso da soli. Dopo aver letto il byte [] è possibile convertire in una stringa di nuovo.

  3. Se avete avuto un sacco di testo per scrivere si potrebbe anche allegare un TextWriter allo stesso flusso. Ma attenzione, gli scrittori vogliono chiudere i loro flussi. Io non consiglio questo, in generale, ma è bene sapere. Anche in questo caso si dovrà segnare un punto in cui l'altro lettore può assumere (colpo di testa fissa funziona bene).

Altri suggerimenti

Ecco perché un BinaryWriter sta scrivendo la rappresentazione binaria della stringa, inclusa la lunghezza della stringa. Se si dovesse scrivere i dati direttamente (ad esempio byte [], ecc), sarà non includere quella lunghezza.

byte[] text = System.Text.Encoding.Unicode.GetBytes("test");
FileStream fs = new FileStream("C:\\test.txt", FileMode.Create);
BinaryWriter writer = new BinaryWriter(fs);
writer.Write(text);
writer.Close();

Si noterà che non include la lunghezza. Se avete intenzione di scrivere i dati testuali utilizzando lo scrittore binario, è necessario convertirlo prima.

Il byte alla partenza è la lunghezza della stringa, è scritto come un numero intero di lunghezza variabile.

Se la stringa è di 127 caratteri o meno, la lunghezza sarà memorizzato come un byte. Quando la stringa colpisce 128 caratteri, la lunghezza viene scritto come 2, e si muoverà a 3 e 4 ad alcune lunghezze pure.

Il problema qui è che si sta utilizzando BinaryWriter, che scrive i dati che BinaryReader può leggere di nuovo in un secondo momento. Se si desidera scrivere in un formato personalizzato della propria, è necessario eliminare le stringhe di scrittura del genere, o far cadere usando BinaryWriter del tutto.

Come Henk ha sottolineato nel questa risposta , questa è la lunghezza della stringa (come a 32 bit int).

Se non si desidera che questo, è possibile scrivere "TEST" manualmente scrivendo i caratteri ASCII per ogni lettera come byte, oppure si potrebbe usare:

System.Text.Encoding.UTF8.GetBytes("TEST")

E scrivere la matrice risultante (che non conterrà un int length)

Quello che stai vedendo è in realtà un intero codificato a 7 bit, che è una sorta di compressione intero .
Il BinaryWriter anteporre il testo con questo modo che i lettori (cioè BinaryReader) sapranno quanto a lungo la stringa scritta è.

Si può leggere di più sui dettagli di implementazione di questo a http://dpatrickcaldwell.blogspot.se/2011/09/7-bit-encoding-with-binarywriter-in-net.html .

È possibile salvarlo come UTF8 codificato array di byte in questo modo:

...

BinaryWriter w = new BinaryWriter(fs);

w.Write(UTF8Encoding.Default.GetBytes("test"));

...

Questo è un segno di ordine di byte, molto probabilmente. È perché la codifica del flusso è impostata su Unicode.

Ricordate che le stringhe Java sono codificate internamente in UTF-16.

Quindi, "test" è in realtà fatta di byte 0xFF, 0xfe (insieme il segno di ordine di byte), 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00.

Probabilmente si desidera lavorare con i byte invece di flussi di caratteri.

Suona come segni di ordine di byte.

http://en.wikipedia.org/wiki/Byte-order_mark

Forse si vuole scrivere la stringa come UTF-8.

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