- saxus blogja
- A hozzászóláshoz be kell jelentkezni
- 727 megtekintés
Hozzászólások
Kód nélkül ez csak pusztába kiáltott szó :D
- A hozzászóláshoz be kell jelentkezni
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
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
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
- A hozzászóláshoz be kell jelentkezni
Ezekszerint a using nemcsak a legfelső streamet zárja le, hanem az összes alatta levőt is. De majd a jobban hozzáértők megmondják.
- A hozzászóláshoz be kell jelentkezni
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
- A hozzászóláshoz be kell jelentkezni
És az nem jó megoldás, ha csinál egy NoDescadingDisposeBinaryReader-t, úgy hogy a Dispose metódusát felülírja, hogy a paramétere 'false' legyen?
- A hozzászóláshoz be kell jelentkezni
De valószínűleg jó, csak nem biztos, hogy megéri emiatt létrehozni egy új osztályt. Egyszerűbb a using() helyett más konstrukciót használni, pl. try-finallyt, de ezt a probléma és a kód ismeretében ő tudja megmondani.
--
ahan nem
- A hozzászóláshoz be kell jelentkezni
Szerintem a Finalize nem hívja.
--
geri / otperc.net
- A hozzászóláshoz be kell jelentkezni
Én nem tudom, az MSDN-ből másoltam az idézetet.
--
ahan nem
- A hozzászóláshoz be kell jelentkezni
Való igaz. Szerintem hülyeséget írnak (talán copy-paste error). Kommenteltem rá egyet, kíváncsi vagyok, mikor javítják.
--
geri / otperc.net
- A hozzászóláshoz be kell jelentkezni
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
- A hozzászóláshoz be kell jelentkezni
Továbbra sem tartom teljesen szép megoldásnak.
----------------
Lvl86 Troll
- A hozzászóláshoz be kell jelentkezni
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
- A hozzászóláshoz be kell jelentkezni
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
- A hozzászóláshoz be kell jelentkezni
"az csak egy wrapper a Stream körül"
Pont ezért ne piszkálja el a streamem. - szerintem.
----------------
Lvl86 Troll
- A hozzászóláshoz be kell jelentkezni
törölve. félre értettem :)
- A hozzászóláshoz be kell jelentkezni
Miért nem rakod az _fs.Seek(0, SeekMode.Begin); a using-on belülre?
A 'using' hatókörében szőnyegbombázással az összes objektumot felszabadítja?
- A hozzászóláshoz be kell jelentkezni
Azzal nem vagyok előrébb. Nekem az kellett volna, hogy a BinaryReader megszűnése után is használható legyen a Stream. De ez nem kivitelezhető -> BinaryReadernek is maradnia kell a streammal.
----------------
Lvl86 Troll
- A hozzászóláshoz be kell jelentkezni
Az nem bonyolult, csak meg kell szüntetni a referenciát:
br = null;
Ha using -ot használsz, az mindig az objektumot Dispose() -olja...
- A hozzászóláshoz be kell jelentkezni