Podczas pracy ze strumieniami binarnymi (tj. Tablice byte[]
), głównym punktem używania BinaryReader
lub BinaryWriter
wydaje się być uproszczony odczyt/zapis pierwotnych typów danych z strumień, używając metod takich jak ReadBoolean()
i biorąc pod uwagę kodowanie. Czy to cała historia? Czy istnieje nieodłączna zaleta lub wada, jeśli pracuje się bezpośrednio z urządzeniem Stream
, bez korzystania z BinaryReader/BinaryWriter
? Większość metod, takich jak Read()
, wydaje się być taka sama w obu klasach i przypuszczam, że działają one identycznie pod spodem.Używanie Stream.Read() vs BinaryReader.Read() do przetwarzania strumieni binarnych
Rozważmy prosty przykład przetwarzania pliku binarnego na dwa różne sposoby (edit: Zdaję sobie sprawę w ten sposób jest nieskuteczny i że bufor może być używany, to tylko przykład):
// 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));
}
}
wyjście być tym samym, ale co się dzieje wewnętrznie (np. z perspektywy OS)? Czy to - ogólnie rzecz biorąc - ważne, która implementacja jest używana? Czy jest jakiś cel używania BinaryReader/BinaryWriter
, jeśli nie potrzebujesz dodatkowych metod, które zapewniają? W tym konkretnym przypadku, MSDN mówi, to w odniesieniu do Stream.ReadByte()
:
Domyślna implementacja na Stream tworzy nową tablicę jednobajtowych a następnie wywołuje Read. Chociaż jest to formalnie poprawne, jest to niewydajne.
Korzystanie GC.GetTotalMemory()
, to pierwsze podejście wydaje się przeznaczyć 2x tyle miejsca jako drugi, ale AFAIK nie powinno to mieć miejsce w przypadku bardziej ogólny sposób Stream.Read()
jest używany (np czytania w kawałki za pomocą bufor). Mimo to wydaje mi się, że te metody/interfejsy można łatwo zunifikować ...
Domyślna implementacja Stream.ReadByte ma być nadmiernie używana w każdej konkretnej implementacji Stream. Co pozostawia pytanie bez odpowiedzi, dlaczego potrzebujemy nowej klasy StreamReader, zamiast być w stanie polegać na (implementacjach) Stream, aby zrobić to, co trzeba? – yoyo
@yoyo, ponieważ klasa Stream jest ogólnie źle zaprojektowana. To jest zbyt "ogólne". Nie wszystkie strumienie obsługują wyszukiwanie lub czytanie (sprawnie) lub czytanie lub pisanie. To po prostu zły projekt OOP. Zamiast tego powinni używać interfejsów. –