Forum Delphi.cz

Delphi => Obecné => Téma založeno: vandrovnik 09-12-2019, 22:23:26

Název: TBufferedFileStream - detekce chyb při zápisu
Přispěvatel: vandrovnik 09-12-2019, 22:23:26
Ahoj,

před chvílí jsem překvapeně zjistil, že když používám pro zápis TBufferedFileStream a během zápisu do souboru dojde místo na disku, nijak se o tom nedovím. Je na to nějaká finta, nebo když potřebujete vyvolat výjimku při chybě zápisu, tak si na to všichni píšete vlastní streamy? On tedy ani normální TFileStream nevyvolá výjimku, ten ale alespoň vrací počet zapsaných bajtů, takže to mohu porovnat s tím, kolik jsem požadoval zapsat. TBufferedFileStream.SyncBuffer jen suše zavolá inherited Write a o výsledek se nestará...

K.
Název: Re:TBufferedFileStream - detekce chyb při zápisu
Přispěvatel: pf1957 10-12-2019, 07:26:44
když potřebujete vyvolat výjimku při chybě zápisu, tak si na to všichni píšete vlastní streamy? On tedy ani normální TFileStream nevyvolá výjimku,
ten ale alespoň vrací počet zapsaných bajtů, takže to mohu porovnat s tím, kolik jsem požadoval zapsat. TBufferedFileStream.SyncBuffer jen suše zavolá inherited Write a o výsledek se nestará...
Ten TBufferedFileStream, to je nejaka "novinka", ne? Celkem me nenapada pripad, kdybych neco takoveho chtel pouzit. Normalne file system OS cachuje, takze to bude spis kontraproduktivni a jedine co jsme pouzivali, bylo v potrebnych pripadech naopak vynutit primy zapis na disk (v pripade ACID zalezitosti) viz https://docs.microsoft.com/en-us/windows/win32/fileio/file-buffering (https://docs.microsoft.com/en-us/windows/win32/fileio/file-buffering).

Jinak Win API nikdy nevyvolava exception, takze standardni chovani je, ze se kontroluje vysledek I/O, kde to Write zakoduje vznik chyby jako nulovou delku a mel bys volat GetLastError ev. RaiseLastOSError apod. a pak ano, je moznost napsat si throwable variantu streamu, coz je cistsi a nebo to na miste po kazdem zapisu pesky zkontrolovat a zahodit. Volba IMHO zalezi, jakym stylem je ta aplikace cela psana: jestli se vic podoba objektovemu navrhu a nebo je to aplikace napsana proceduralnim stylem s uzitim objektu :-)

Název: Re:TBufferedFileStream - detekce chyb při zápisu
Přispěvatel: vandrovnik 10-12-2019, 09:24:12
Co jsem tak zkoušel, tak když se čte/zapisuje mnohokrát po malých objemech dat, je tBufferedFileStream o dost rychlejší (v mém případě třeba pro čtení a zápis DXF, nejlépe ještě ze síťového disku). Bohužel tím, že při zápisu cache vůbec neřeší, jestli se zápis podařil nebo ne, je tak nějak k ničemu - nenapadá mě žádný případ, kdy bych nepodařený zápis mohl tiše ignorovat a nechal uživatele, aby byl později překvapen...
Název: Re:TBufferedFileStream - detekce chyb při zápisu
Přispěvatel: pf1957 10-12-2019, 16:52:03
Bohužel tím, že při zápisu cache vůbec neřeší, jestli se zápis podařil nebo ne, je tak nějak k ničemu - nenapadá mě žádný případ, kdy bych nepodařený zápis mohl tiše ignorovat a nechal uživatele, aby byl později překvapen...
Mozna bys mohl pred operaci Write zavolat SetLastError(ERROR_SUCCESS) a po skonceni otestovat GetLastError. Write je narozdil od SyncBuffer virtualni, takze by se dal udelat potomek treba TBufferedFileStreamThrowable s prekrytou metodou Write, kam bys to nacpal. A udelat analogicky throwable i ostastni metody. A nebo si holt napsat z gruntu vlastni a poradne.
Název: Re:TBufferedFileStream - detekce chyb při zápisu
Přispěvatel: vandrovnik 10-12-2019, 17:00:04
Až bude chvilka, napíšu si radši vlastní.
Ale je to další nedotažená věc, co člověka akorát naštve, když na ni narazí.
Název: Re:TBufferedFileStream - detekce chyb při zápisu
Přispěvatel: pepak 10-12-2019, 17:36:11
Popravdě mě překvapuje, že někdo (v tomto případě programátoři EMBT) používá TStream.Write a ne rovnou TStream.WriteBuffer, který by tu výjimku vyhodil.

Btw., díval jsem se a:

1) Třída přibyla v Delphi 10.1.

2) Nechápu vůbec, proč to je potomek TFileStream. Proč proboha se zrovna v tom jednom případě, kdy to Java má dobře, nemohli inspirovat u ní a neudělat to jako Decorator pro libovolný TStream? (Pro neznalé: Decorator je v tomto případě potomek TStream, který dostane jiný TStream v konstruktoru a na tento jiný TStream přesměrovává všechny funkce, které nechce implementovat sám.)

3) Metoda TBufferedFileStream.SyncBuffer je natolik blbě (zahazuje všechny chyby), že bych skoro raději tento stream nepoužíval a napsal si vlastní. Není to tak těžké.
Název: Re:TBufferedFileStream - detekce chyb při zápisu
Přispěvatel: Radek Červinka 10-12-2019, 17:37:16
Až bude chvilka, napíšu si radši vlastní.
Ale je to další nedotažená věc, co člověka akorát naštve, když na ni narazí.

Prosím, zkus to reportovat a pokud ano, dej sem odkaz. Mám pro to důvod...
Název: Re:TBufferedFileStream - detekce chyb při zápisu
Přispěvatel: vandrovnik 10-12-2019, 17:43:24
https://quality.embarcadero.com/browse/RSP-27181 (https://quality.embarcadero.com/browse/RSP-27181)

Tak schválně, která pětiletka...
Název: Re:TBufferedFileStream - detekce chyb při zápisu
Přispěvatel: vandrovnik 10-12-2019, 17:46:00
2) Nechápu vůbec, proč to je potomek TFileStream.

Mám dojem, že v novinkách psali, jak je úžasné, že kdekoli se používalo tFileStream.Create..., může se rovnou použít tBufferedFileStream.Create..., takže bez dalších změn ve vlastním kódu se získá vyšší výkon.
Název: Re:TBufferedFileStream - detekce chyb při zápisu
Přispěvatel: pepak 10-12-2019, 18:19:19
Mám dojem, že v novinkách psali, jak je úžasné, že kdekoli se používalo tFileStream.Create..., může se rovnou použít tBufferedFileStream.Create..., takže bez dalších změn ve vlastním kódu se získá vyšší výkon.
Panebože.

No nic, radši nebudu spekulovat o tom, jak moc je úspora malého množství psaní (přepsání TFileStream.Create(...) na TBufferedFileStream.Create(...)) přínosná oproti tomu, že sice budeme muset napsat o pár písmenek víc (TBufferedStream.Create(TFileStream.Create(...))), ale bude to fungovat pro jakýkoliv stream. Za mě to je přesně jedna z těch ukázek, proč Delphi nejsou moderní jazyk (viz vedlejší vlákno) - tohle sice striktně vzato není věc jazyka, ale ukazuje to na styl uvažování jeho tvůrců, což se následně projevuje jinde.
Název: Re:TBufferedFileStream - detekce chyb při zápisu
Přispěvatel: vandrovnik 10-12-2019, 18:29:34
Možná jsem to napsal nepřesně a vyznělo to hůř, ale pointa byla, že se tFileStream dá nahradit tím tBufferedFileStream. Je ale fakt, že když už někdo pracuje se streamy, tak většinou akceptuje jakýkoli tStream, takže nemuseli dědit od tFileStream.
Název: Re:TBufferedFileStream - detekce chyb při zápisu
Přispěvatel: pf1957 11-12-2019, 09:11:20
budeme muset napsat o pár písmenek víc (TBufferedStream.Create(TFileStream.Create(...)))
Jenom par pismenek to nejspis nebude, protoze se musis postarat o zivotni cyklus 2 instanci a musel bys konec zivotniho cyklu predaneho streamu delegovat na TBufferedStream. Ale zase vydavat ze strany EMBT substitutici jmena tridy za buhvi jakou vyhodu, kdyz tech vyskytu v aplikaci bude v podstate par a ne jako u typu String mi prijde irelevantni, kdyz nekdo honi rychlost. Treba v C# je FileStream automaticky bufferovany...

Ale to bych jim nezazlival, kdyby to implementovali alespon poradne. I/O operace bez kontroly, to je neodpustitelny slendrian  >:(

Citace
tohle sice striktně vzato není věc jazyka, ale ukazuje to na styl uvažování jeho tvůrců, což se následně projevuje jinde.
IMHO je to dusledkem, ze se v Delphi neuci moderni programovani (treba tohle je 10+ let stara zalezitost: http://prog-story.technicalmuseum.cz/images/dokumenty/Programovani-TSW-1975-2014/2006/2006-03.pdf (http://prog-story.technicalmuseum.cz/images/dokumenty/Programovani-TSW-1975-2014/2006/2006-03.pdf) a design patterns se objevilly v podstate ve stejne dobe jako Delphi a Java... Ja uz taky nikdy pod kuzi nedostanu jako nativni pristupy composition over inheritance a programovani proti interfacum jako to predvadel treba Delfin. Ale jsem uz starej cur*k, t.c. jako spokojeny duchodce  ;)
Název: Re:TBufferedFileStream - detekce chyb při zápisu
Přispěvatel: pf1957 11-12-2019, 09:15:17
https://quality.embarcadero.com/browse/RSP-27181 (https://quality.embarcadero.com/browse/RSP-27181)

Tak schválně, která pětiletka...
Aspon jsem ti tam dal hlas, kdyz se tak snazis ;)
Název: Re:TBufferedFileStream - detekce chyb při zápisu
Přispěvatel: Radek Červinka 11-12-2019, 12:47:34
Napsal mi oxo:

Novější Delphi obsahují mojí unitu Xml.Internal.OBufferedStreams.pas,
která má implementaci read/write buffered streamu. Kdysi dávno jsem tam
měl bug a byl i v Delphi, který jsem už opravil, ale nevím, jestli si ho
upravili i v Delphi.

TOBufferedWriteStream
TOBufferedReadStream
Název: Re:TBufferedFileStream - detekce chyb při zápisu
Přispěvatel: miroB 12-12-2019, 11:58:24
Napsal mi oxo:

Novější Delphi obsahují mojí unitu Xml.Internal.OBufferedStreams.pas,
která má implementaci read/write buffered streamu. Kdysi dávno jsem tam
měl bug a byl i v Delphi, který jsem už opravil, ale nevím, jestli si ho
upravili i v Delphi.

TOBufferedWriteStream
TOBufferedReadStream
Táto informácia nie je úplná.
Mám tri verzie Delphi dozadu. Nie Rio, ale tri pred ňou.
Všade je ten súbor.
Podľa porovnávania sa javí rovnaký.
Je teda spoľahlivý/opravený, alebo je chybný?
Keby som to vedel, malo by to zmysel. Verím, že nielen pre mňa.
Bolo by super, keby priamo emb. udržiavalo nejaký zoznam opravených funkcionalít.
Prípadne aj zoznam tých "pokazených"