Quando si lavora con flussi binari (ovvero gli array byte[]
), il punto principale dell'utilizzo di BinaryReader
o BinaryWriter
sembra essere la lettura/scrittura semplificata di tipi di dati primitivi da uno stream, utilizzando metodi come ReadBoolean()
e prendendo in considerazione la codifica. È tutta la storia? C'è un vantaggio o svantaggio intrinseco se si lavora direttamente con uno Stream
, senza utilizzare BinaryReader/BinaryWriter
? La maggior parte dei metodi, come ad esempio Read()
, sembra essere la stessa in entrambe le classi e la mia ipotesi è che funzionino in modo identico al di sotto.Utilizzo di Stream.Read() vs BinaryReader.Read() per elaborare flussi binari
consideri un semplice esempio di elaborazione di un file binario in due modi diversi (edit: mi rendo conto che in questo modo è inefficace e che un buffer può essere utilizzato, è solo un esempio):
// Using FileStream directly
using (FileStream stream = new FileStream("file.dat", FileMode.Open))
{
// Read bytes from stream and interpret them as ints
int value = 0;
while ((value = stream.ReadByte()) != -1)
{
Console.WriteLine(value);
}
}
// Using BinaryReader
using (BinaryReader reader = new BinaryReader(FileStream fs = new FileStream("file.dat", FileMode.Open)))
{
// Read bytes and interpret them as ints
byte value = 0;
while (reader.BaseStream.Position < reader.BaseStream.Length)
{
value = reader.ReadByte();
Console.WriteLine(Convert.ToInt32(value));
}
}
l'uscita sarà essere lo stesso, ma cosa sta succedendo internamente (ad esempio dal punto di vista del sistema operativo)? In generale, è importante quale implementazione viene utilizzata? C'è qualche motivo per usare BinaryReader/BinaryWriter
se non hai bisogno dei metodi extra che forniscono? Per questo caso specifico, MSDN dice questo per quanto riguarda Stream.ReadByte()
: implementazione
L'impostazione predefinita in funzione crea un nuovo array singolo byte e quindi chiama Read. Mentre questo è formalmente corretto, è inefficiente.
Utilizzando GC.GetTotalMemory()
, questo primo approccio sembra allocare 2x più spazio la seconda, ma AFAIK questo non dovrebbe essere il caso se un metodo più generale Stream.Read()
viene utilizzato (ad esempio per la lettura in blocchi utilizzando un buffer). Tuttavia, mi sembra che questi metodi/interfacce possano essere facilmente unificati ...
L'implementazione predefinita di Stream.ReadByte è destinata a essere superata in qualsiasi implementazione concreta di Stream. Il che lascia la domanda senza risposta, perché abbiamo bisogno di una nuova classe StreamReader invece di essere in grado di fare affidamento su (Streaming di) Stream per fare la cosa giusta? – yoyo
@yoyo perché la classe Stream è mal progettata in generale. È troppo "generale". Non tutti i flussi supportano la ricerca o ReadByte (in modo efficiente) o la lettura o la scrittura. È solo un cattivo design OOP. Dovrebbero aver usato invece le interfacce. –