.NET, Streams

Aki a .NET-ben a Streamsokat tervezte, annak minimum kijárna egy faszkorbács.

Az mi már, hogy egy FileStream->DeflateStream->MemoryStream bejárása esetén nekem kell kézzel pakolgatni a FileStreamból a ganajt?

A sokak által lesajnált Delphiben olyan szépen működött a Decorator pattern a Streamokkal, nem értem, hogy kúrhatták el ezt ennyire a .NET-ben.

Hozzászólások

Kód nélkül ez csak pusztába kiáltott szó :D

Elég végignézni az MSDN-n.

Egyébként az éppen aktuális kedvencem az elmúlt két percben a BinaryReader lett.

Tervem az lett volna, hogy megnyitok egy FileStream-t, amibe majd időnként beleolvasok. (Egyszer kell az elejéről egy tartalomjegyzéket, utána a többi adatot). Namost, ezzel az a gond, hogy az using végén lezárja a Streamot is. Ami nekem rossz.

_fs = new FileStream(@"tamtaramtatam.bin", FileMode.Read);

using (BinaryReader br = new BinaryReader(_fs)) {
  // tamtaramtatam...
} // ?!?!?.

_fs.Seek(0, SeekMode.Begin);  // Exception, merthogy disposed.

----------------
Lvl86 Troll

using használatával ez várható:
http://msdn.microsoft.com/en-us/library/yh598w02%28VS.80%29.aspx

Ha nem erre van szükséged akkor ne használd, ez esetben viszont kézzel kell gondoskodnod a stream által használt erőforrások elengedéséről.

Azért a fenti cikkből kiemelnék egy mondatot: However, it is usually best to release limited resources such as file handles and network connections as quickly as possible.

Szerintem nem érted a problémám:

- adott egy nyitott FileStream, aminek nyitva kell lennie az alkalmazás futásakor. (Lényegében csomagfájlok, előreláthatólag kevesebb, mint 10, viszont kisebb adatfolyamokat sűrűbben akarok kiolvasni belőle. Ezért kár újranyitni őket.)

- ráeresztenék egy BinaryReader-t, hogy olvassak belőle. Mikor felszabadul, bezárja a FileStream-t. Miért? Olyan, mintha egy e-book olvasó törölné az éppen olvasott könyvet a gépről, merthogy kikapcsoltam.

Mi van, ha én ez után esetleg egy BinaryWriter-t akarok ráereszteni? Myissam újra a fájlt?

----------------
Lvl86 Troll

Idezet a BinaryReader.Dispose() dokumentaciojabol:

"This method is called by Dispose and Finalize. By default, this method specifies the disposing parameter as true. Finalize specifies the disposing parameter as false.

When the disposing parameter is true, this method releases all resources held by any managed objects that this BinaryReader references. This method invokes the Dispose method of each referenced object."

Ne hasznalj using()-ot, mert ilyen esetekben ez nyilvan nem hasznalhato. Dispose-old magadnak a BinaryReadert, amikor az szukseges.
--
ahan nem

Azt mondja nekem az intellisense a .Close()-ra, hogy "Closes the current reader and the underlying stream.", úgyhogy ez nem túl meglepő módon lezárja a mögötte lévő stream-et is.
A BinaryReader-nek egyébként nincs finalizere, úgyhogy ha nem hívsz rá explicit Close()-t, Dispose()-t, vagy nem teszed implicit ugyanezt egy using blokkal, akkor a GC magától nem fogja lezárni a readert (így a streamed sem).
--
geri / otperc.net

Pedig altalaban szebb, mert nem kell annyiszor Dispose-olni ahany uj objektumot hozol letre, pl ilyen esetekben:


using (FileStream fs = new FileStream(@"tamtaramtatam.bin", FileMode.Read))
{
  using (BinaryReader br = new BinaryReader(fs)) 
  {
    // ahan
  } 
}

A fenti helyett irhatod ezt, es nem lesz belole problema:


using (BinaryReader br = new BinaryReader(new FileStream(@"tamtaramtatam.bin", FileMode.Read))) {
  // ahan
} 

Es az ennel cifrabb konstrukciok sem feltetlen szamitanak durvanak. Olvashatobb igy a kod. Most neked ez epp rosszul jott, de attol ez meg nem olyan rossz megoldas.
--
ahan nem

Hogy ha lezárod, lezáródik, ha nem zárod le, nem záródik. Rettenet. :)
Effektíve a BinaryReaderen nem nagyon van mit lezárni, az csak egy wrapper a Stream körül, némi buffering és adatkonverziós szolgáltatásokkal. Nem történik semmi, ha nem zárod le, szépen kisöpri majd a GC.
De ha semmiképp nem tudsz együttélni ezzel, mind a Close, mind a Dispose virtual, írd felül őket a MyBetterBinaryReader implementációdban.
--
geri / otperc.net