Autor Téma: TBufferedFileStream - detekce chyb při zápisu  (Přečteno 359 krát)

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 867
  • Karma: 45
    • Verze Delphi: 10.3
TBufferedFileStream - detekce chyb při zápisu
« kdy: 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.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2645
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:TBufferedFileStream - detekce chyb při zápisu
« Odpověď #1 kdy: 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.

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 :-)


Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 867
  • Karma: 45
    • Verze Delphi: 10.3
Re:TBufferedFileStream - detekce chyb při zápisu
« Odpověď #2 kdy: 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...

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2645
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:TBufferedFileStream - detekce chyb při zápisu
« Odpověď #3 kdy: 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.

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 867
  • Karma: 45
    • Verze Delphi: 10.3
Re:TBufferedFileStream - detekce chyb při zápisu
« Odpověď #4 kdy: 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í.

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1462
  • Karma: 35
    • Pepak.net
Re:TBufferedFileStream - detekce chyb při zápisu
« Odpověď #5 kdy: 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é.

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2433
  • Karma: 103
    • Verze Delphi: D5,D2007, DXE, DXE2 + 2 poslední (Tokyo)
    • O Delphi v češtině
Re:TBufferedFileStream - detekce chyb při zápisu
« Odpověď #6 kdy: 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...
Embarcadero MVP - Czech republic

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 867
  • Karma: 45
    • Verze Delphi: 10.3
Re:TBufferedFileStream - detekce chyb při zápisu
« Odpověď #7 kdy: 10-12-2019, 17:43:24 »
https://quality.embarcadero.com/browse/RSP-27181

Tak schválně, která pětiletka...

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 867
  • Karma: 45
    • Verze Delphi: 10.3
Re:TBufferedFileStream - detekce chyb při zápisu
« Odpověď #8 kdy: 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.

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1462
  • Karma: 35
    • Pepak.net
Re:TBufferedFileStream - detekce chyb při zápisu
« Odpověď #9 kdy: 10-12-2019, 18:19:19 »
Excellent
Rated 1 time
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.

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 867
  • Karma: 45
    • Verze Delphi: 10.3
Re:TBufferedFileStream - detekce chyb při zápisu
« Odpověď #10 kdy: 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.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2645
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:TBufferedFileStream - detekce chyb při zápisu
« Odpověď #11 kdy: 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 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  ;)
« Poslední změna: 11-12-2019, 09:19:35 od pf1957 »

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2645
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:TBufferedFileStream - detekce chyb při zápisu
« Odpověď #12 kdy: 11-12-2019, 09:15:17 »
https://quality.embarcadero.com/browse/RSP-27181

Tak schválně, která pětiletka...
Aspon jsem ti tam dal hlas, kdyz se tak snazis ;)

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2433
  • Karma: 103
    • Verze Delphi: D5,D2007, DXE, DXE2 + 2 poslední (Tokyo)
    • O Delphi v češtině
Re:TBufferedFileStream - detekce chyb při zápisu
« Odpověď #13 kdy: 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
Embarcadero MVP - Czech republic

Offline miroB

  • Guru
  • *****
  • Příspěvků: 554
  • Karma: 17
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:TBufferedFileStream - detekce chyb při zápisu
« Odpověď #14 kdy: 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"