Zjištění chyby při neúspěchu fwrite()

A. F.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #30 kdy: 30. 06. 2018, 21:25:40 »
Mimo špatného "algoritmu", je $handle globalní proměnná, která v té funkci write není vidět, takže by to nemělo fungovat vůbec a případně ještě řvát.

Jinak je v PHP taky funkce file_put_contents, která tě takového šaškování zbaví.
To jsem to jen špatně přepsal.

file_put_contents se mi nehodí, protože pracuji s tím handle. A pokud je to tak jak píše BoneFlute, že stejně jen vypíše chybovku na výstup, tak se mi to nehodí už vůbec a nebudu to tedy přepisovat.


Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #31 kdy: 30. 06. 2018, 21:26:48 »
Děti ve školce znají věc jako zacyklení. Ty ne?
K zacyklení dojde jedině tehdy, pokud v cyklu není nikdy splněna podmínka, která by cyklus ukončila.

Teda „programátor“, který se bojí používat cykly, protože neumí napsat ukončovací podmínku, to je fakt něco.

Takže doporučuješ kód, který v případě, že dojde místo na disku, tak se zacyklí?
Z mých komentářů nic takového neplyne. Pokud funkce fwrite() v PHP je implementovaná tak, jak je popsaná v dokumentaci, vrátí v případě zaplnění disku FALSE. I kdyby fungovala jinak a v případě chyby mohla vracet i nulu, pořád se akorát ten test na úspěch funkce upraví tak, zda vrátila hodnotu větší než nula.

Furt lepší, než co navrhuješ ty.
Ne, kód, který občas náhodně nefunguje, není lepší.

BoneFlute

  • *****
  • 2 000
    • Zobrazit profil
Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #32 kdy: 30. 06. 2018, 21:30:45 »
...dojde k chybě, tak cyklus přerušit.
Pokud je plnej disk, tak to fwrite() neeviduje jako chybu.

A jako vůbec, von se tu dotyčný táže, jak zjistit že je nějaká chyba, a vy mu radíte, že má blbě algoritmus, kterej nakonec opravíte do ještě horšího stavu. To myslíte vážně?

BoneFlute

  • *****
  • 2 000
    • Zobrazit profil
Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #33 kdy: 30. 06. 2018, 21:34:35 »
Děti ve školce znají věc jako zacyklení. Ty ne?
K zacyklení dojde jedině tehdy, pokud v cyklu není nikdy splněna podmínka, která by cyklus ukončila.

Teda „programátor“, který se bojí používat cykly, protože neumí napsat ukončovací podmínku, to je fakt něco.
To jsi jako sebral kde?


Takže doporučuješ kód, který v případě, že dojde místo na disku, tak se zacyklí?
Z mých komentářů nic takového neplyne. Pokud funkce fwrite() v PHP je implementovaná tak, jak je popsaná v dokumentaci, vrátí v případě zaplnění disku FALSE. I kdyby fungovala jinak a v případě chyby mohla vracet i nulu, pořád se akorát ten test na úspěch funkce upraví tak, zda vrátila hodnotu větší než nula.
No konečně to chápeš. Že se vůbec pouštíš do něčeho, čemu nerozumíš.


Furt lepší, než co navrhuješ ty.
Ne, kód, který občas náhodně nefunguje, není lepší.
Beru na vědomí. Zacyklení je lepší.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #34 kdy: 30. 06. 2018, 21:35:04 »
Pokud je plnej disk, tak to fwrite() neeviduje jako chybu.
Takže pokračuje v zápisu za konec disku? Nebo co přesně fwrite() vrátí, když je plnýdisk?

A jako vůbec, von se tu dotyčný táže, jak zjistit že je nějaká chyba, a vy mu radíte, že má blbě algoritmus, kterej nakonec opravíte do ještě horšího stavu. To myslíte vážně?
Ne, ten algoritmus byl špatně a tvrdil, že došlo k chybě, i když to není pravda. Když se bude volat fwrite() v cyklu a testovat, zda se něco zapsalo nebo došlo k chybě, bude to fungovat správně.

Vy už byste se k tomu měl přestat vyjadřovat, když je pro vás nepochopitelný i obyčejný cyklus, nemáte k tomu co říci.


BoneFlute

  • *****
  • 2 000
    • Zobrazit profil
Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #35 kdy: 30. 06. 2018, 21:39:25 »
Pokud je plnej disk, tak to fwrite() neeviduje jako chybu.
Takže pokračuje v zápisu za konec disku? Nebo co přesně fwrite() vrátí, když je plnýdisk?
[facepalm]


A jako vůbec, von se tu dotyčný táže, jak zjistit že je nějaká chyba, a vy mu radíte, že má blbě algoritmus, kterej nakonec opravíte do ještě horšího stavu. To myslíte vážně?
Ne, ten algoritmus byl špatně a tvrdil, že došlo k chybě, i když to není pravda. Když se bude volat fwrite() v cyklu a testovat, zda se něco zapsalo nebo došlo k chybě, bude to fungovat správně.

Vy už byste se k tomu měl přestat vyjadřovat, když je pro vás nepochopitelný i obyčejný cyklus, nemáte k tomu co říci.
Fakt žeru tyhle lidi s bujnou fantazií.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #36 kdy: 30. 06. 2018, 21:44:06 »
0 jako korektní hodnota je nesmysl, protože vždycky se musí něco zapsat.
Je možné, že nadstavba PHP chování mění, ale standardní POSIXový write může vrátit i nulu jako normální hodnotu – zapsat se nic nemusí. Při nedostatku místa OS vrátí -1 a v errno bude ENOSPC.

Při zápisu do souboru se bude OS snažit zapsat vše, ale nemusí se mu to podařit. O to je to horší, že to bude skoro vždy fungovat, ale pak se někdy „nepochopitelně“ zapíše jen část.

POSIXový write() může vrátit 0 v případě, že velikost zapisovaných dat byla 0. Pokud OS nemůže nic zapsat v případě neprázdných argumentů, má vrátit chybu EAGAIN, aby program mohl počkat přes select() (nebo podobnou funkci) na to, až zápis bude možný. Kdyby vracel 0, tak by to skončilo bez kontroly v busy loop.

To, že PHP si překládá chybu na 0, je jiná věc (nejspíš, aby se dalo snadno testovat v podmínce), ale v zásadě to na věci nic nemění - zapisovat prázdné data je stejně nesmysl.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #37 kdy: 30. 06. 2018, 21:58:53 »
POSIXový write() může vrátit 0 v případě, že velikost zapisovaných dat byla 0. Pokud OS nemůže nic zapsat v případě neprázdných argumentů, má vrátit chybu EAGAIN, aby program mohl počkat přes select() (nebo podobnou funkci) na to, až zápis bude možný. Kdyby vracel 0, tak by to skončilo bez kontroly v busy loop.
POSIXový write může vrátit 0 i v případě, že je požadován zápis nenulového počtu bajtů. A znamená to jen, že bylo zapsáno nula bajtů – není to chyba.

Citace
On success, the number of bytes written is returned (zero indicates nothing was written).  It is not an error if this number is smaller than the number of bytes requested; this may happen for example because the disk device was filled.  See also NOTES.

On error, -1 is returned, and errno is set appropriately.

Vrácení 0 by měl být výjimečný případ, ale počítá se mezi úspěšné výsledky volání. Nekonečnému cyklu zabrání to, že takový stav by byl jen dočasný, a v některém z příštích cyklů by write mělo něco zapsat nebo skončit chybou.

.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #38 kdy: 30. 06. 2018, 22:01:56 »
Pokud je plnej disk, tak to fwrite() neeviduje jako chybu.
Tak vrátí nulu, kterou vyhodnotíš jako chybu! Jo, ten příklad v dokumentaci je na hovno.

A jako vůbec, von se tu dotyčný táže, jak zjistit že je nějaká chyba, a vy mu radíte, že má blbě algoritmus, kterej nakonec opravíte do ještě horšího stavu. To myslíte vážně?
Protože v první řadě to má tak blbě, že to co vidí jako chybu, nemusí být chyba.

Když jsi tak vykulenej z trviálních věcí, tak se k tomu prostě nevyjadřuj, protože o tom víš kulový a jen se ztrapňuješ.

.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #39 kdy: 30. 06. 2018, 22:08:41 »
Vrácení 0 by měl být výjimečný případ, ale počítá se mezi úspěšné výsledky volání.
fwrite v PHP při záporné návratovce write vrací nulu. Šlo by si s tím hrát, ale prakticky nemá smysl to hned vyhodnodit jako konečnou chybu.

.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #40 kdy: 30. 06. 2018, 22:11:45 »
vyhodnodit jako konečnou chybu.
nevyhodnotit

BoneFlute

  • *****
  • 2 000
    • Zobrazit profil
Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #41 kdy: 30. 06. 2018, 22:14:12 »
0 jako korektní hodnota je nesmysl, protože vždycky se musí něco zapsat.
Je možné, že nadstavba PHP chování mění, ale standardní POSIXový write může vrátit i nulu jako normální hodnotu – zapsat se nic nemusí. Při nedostatku místa OS vrátí -1 a v errno bude ENOSPC.

Při zápisu do souboru se bude OS snažit zapsat vše, ale nemusí se mu to podařit. O to je to horší, že to bude skoro vždy fungovat, ale pak se někdy „nepochopitelně“ zapíše jen část.

POSIXový write() může vrátit 0 v případě, že velikost zapisovaných dat byla 0. Pokud OS nemůže nic zapsat v případě neprázdných argumentů, má vrátit chybu EAGAIN, aby program mohl počkat přes select() (nebo podobnou funkci) na to, až zápis bude možný. Kdyby vracel 0, tak by to skončilo bez kontroly v busy loop.

To, že PHP si překládá chybu na 0, je jiná věc (nejspíš, aby se dalo snadno testovat v podmínce), ale v zásadě to na věci nic nemění - zapisovat prázdné data je stejně nesmysl.
Jen doplním - Pokud zapíšu alespoň jeden bajt, tak je to v pořádku a můžu zkusit znova. Ale pokud se nepovede zápis ani jednoho, není důvod k optimismu si myslet že v příštím kole to bude lepší. Takže dávám tak dva tři pokusy maximálně.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #42 kdy: 30. 06. 2018, 22:16:49 »
fwrite v PHP při záporné návratovce write vrací nulu. Šlo by si s tím hrát, ale prakticky nemá smysl to hned vyhodnodit jako konečnou chybu.
Díky, konečně někdo napsal, jak to je, ne jen nějaké dohady.

Předpokládám, že to byl překlep, a že jste chtěl napsat, že 0 jako návratová hodnota PHP fwrite() by měla být hned vyhodnocena jako chyba.

Každopádně mi to teda připadá jako dost zásadní chyba v dokumentaci PHP. Jednoduché porovnání fwrite() == FALSE sice bude fungovat díky automatickému přetypování, ale třeba už to, co je tam uvedené jako příklad, kvůli === fungovat nebude.

A. F.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #43 kdy: 30. 06. 2018, 22:27:16 »
fwrite() return values jsou docela zmatené, obojí false a 0 znamenají chybu. false je chyba v parametrech, zatímco 0 je chyba provádění (typicky chyba vrácená OS - out of space apod.). Více detailů první komentář v dokumentaci. 0 jako korektní hodnota je nesmysl, protože vždycky se musí něco zapsat. V případě, že by došlo k blokování a je nastaven NONBLOCK, vrací se chyba EAGAIN. Předpokládám, že v rámci "kompatibility" je dobré ošetřít false a 0 stejně :-)

V tom kódu je třeba zpracovat error_get_last na místě, kde se vyhazuje výjimka, tam se vrátí asi finální chyba. Kromě toho jsou tam k opravě následující:
  • loop while writte != 0 místo jednoho if (i když technicky vzato běžné OS zapíšou všechno co jde, pokud jde o normální soubor, jinak je to u pipe, socket apod)/li]
    • nevím, jak je to u php s konverzí znakových sad a DOS/UNIX konverzí, soubor musí být v každém případě otevřen jako binary.
    • ... a podobně jako v předchozím - viz poslední argument, který vypíná magic chování, které rovněž může ovlivnit délku zápisu.
Tak v mém případě se jedná o normální soubor, takže předpokládám, že netřeba to prožívat.

A já mám právě problém v tom, že mi to žádnou chybu nevrátí. To je to co řeším.[/list]

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #44 kdy: 30. 06. 2018, 22:36:13 »
A já mám právě problém v tom, že mi to žádnou chybu nevrátí. To je to co řeším.
Že došlo k chybě zjistíte tak, že otestujete výsledek volání fwrite(), zda je to FALSE nebo 0. Když funkce vrátí hodnotu větší než nula, opakujete její volání v cyklu a zapíšete další část.