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

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #15 kdy: 30. 06. 2018, 18:36:01 »
Opakování zápisu je použito už v tom kódu
Ne, není. Jak jste přišel na to, že při druhém volání se zapíše vše? Volání se musí opakovat tak dlouho, dokud nejsou zapsaná všechna data. Používají se k tomu cykly.
Doufám @andreaw.fean, že tě nenapadne se jeho radou řídit :-)


Lol Phirae

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #16 kdy: 30. 06. 2018, 18:51:01 »
<heap of sh*t snipped>

Poslechni Jirsáku, tady maj něco pro tebe - možná bys mohl být ohleduplný k ostatním a taky na svůj hormonální cyklus upozornit... Ono je to nesnesitelné i normálně, ale dneska už jseš opravdu zralej na ránu bazukou.

 :o ??? ::)

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #17 kdy: 30. 06. 2018, 18:52:52 »
Je mi líto, ale žádné úžasné řešení asi neexistuje.

Funkce fwrite() je jen alias na php_stream_write() a ten nijak zvlášť neřeší důvod nezápisu.
Funkce file_put_contents() sice zařve, že se nepovedlo zapsat ale přičinu, "possibly out of free disk space" si bohapustě vycucá z prstu. Je fakt, že to bude nejčastější příčina, protože práva etc si zjistíš už při fopen().
Pokud skutečně dojde k chybě (což zjistíte testem, zda hodnota vrácená funkci fwrite() je FALSE), bude nejspíš kód chyby v posix_get_last_error(). PHPčkové fwrite je jenom obálka nad libc fwrite(), která vrací chybu v errno, a tuhle hodnotu vrací právě posix_get_last_error().

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #18 kdy: 30. 06. 2018, 18:54:27 »
Doufám @andreaw.fean, že tě nenapadne se jeho radou řídit :-)
Bacha na to, povídat si sám se sebou, to už je nemoc…

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #19 kdy: 30. 06. 2018, 19:00:56 »
Je mi líto, ale žádné úžasné řešení asi neexistuje.

Funkce fwrite() je jen alias na php_stream_write() a ten nijak zvlášť neřeší důvod nezápisu.
Funkce file_put_contents() sice zařve, že se nepovedlo zapsat ale přičinu, "possibly out of free disk space" si bohapustě vycucá z prstu. Je fakt, že to bude nejčastější příčina, protože práva etc si zjistíš už při fopen().
Pokud skutečně dojde k chybě (což zjistíte testem, zda hodnota vrácená funkci fwrite() je FALSE), bude nejspíš kód chyby v posix_get_last_error(). PHPčkové fwrite je jenom obálka nad libc fwrite(), která vrací chybu v errno, a tuhle hodnotu vrací právě posix_get_last_error().
Není. Nezjistíš.


A. F.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #20 kdy: 30. 06. 2018, 19:04:23 »
Opakování zápisu je použito už v tom kódu
Ne, není. Jak jste přišel na to, že při druhém volání se zapíše vše? Volání se musí opakovat tak dlouho, dokud nejsou zapsaná všechna data. Používají se k tomu cykly.
Doufám @andreaw.fean, že tě nenapadne se jeho radou řídit :-)
Udělat si tam cyklus? Nejsem blbej.

Problém skutečně byl v tom nedostatku místa.
Přidal jsem si tam test pomocí funkce disk_free_space. Problém to nevyřeší, ale budu vědět co je to za problém.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #21 kdy: 30. 06. 2018, 19:05:06 »
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.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #22 kdy: 30. 06. 2018, 19:37:47 »
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.
Ten komentář je 8 let starý, chování se mohlo změnit. Připadá mi divné, že by se za 8 let tak zásadní chyba v dokumentaci neopravila. Ale neověřoval jsem to.

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.

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #23 kdy: 30. 06. 2018, 20:31: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.
Ten komentář je 8 let starý, chování se mohlo změnit. Připadá mi divné, že by se za 8 let tak zásadní chyba v dokumentaci neopravila. Ale neověřoval jsem to.

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.

Nemůžeš tu podmínku hodit do cyklu. Musíš testovat, zda návratová hodnota je větší jak 0 - jak píše @kvr kvr, pak teprve můžeš zkusit zapsat znova. @andreaw.fean zvolil opačnou strategii, a při neúspěchu prostě končí - což je v pořádku.
Ty posixový funkce nefungují.
fwrite() není wrapper nad posixovým fwrite...

Sečteno a podtrženo problém je v tom, že tvá rada byla úplně špatná.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #24 kdy: 30. 06. 2018, 21:02:02 »
Nemůžeš tu podmínku hodit do cyklu.
Nízkoúrovňové čtení nebo zápis z/do streamnů (soubory, sokety apod.) vždy může zpracovat menší množství dat, než bylo požadováno, proto se musí opakovat v cyklu. To snad vědí programátoři už ve školce.

Musíš testovat, zda návratová hodnota je větší jak 0 - jak píše @kvr kvr, pak teprve můžeš zkusit zapsat znova.
U toho nízkoúrovňového zápisu představuje chybu jen záporná hodnota. Je možné, že PHP to má zařízené tak, aby se vždy zapsal alespoň jeden bajt, a nula také znamená chybu, ale pak je vážná chyba v dokumentaci, že to tam není napsané.

@andreaw.fean zvolil opačnou strategii, a při neúspěchu prostě končí - což je v pořádku.
V pořádku ovšem není, že končí chybou i v případě úspěšného (částečného) zápisu.

Ty posixový funkce nefungují.
Jasně, vy jste expert na všechno a chyba je v Linuxu nebo jakou implementaci POSIXu myslíte. To sedí od někoho, kdo ani neví, jak zkopírovat data z jednoho souboru do druhého.

Sečteno a podtrženo problém je v tom, že tvá rada byla úplně špatná.
Že vám programování moc nejde jsem pochopil už v sousední diskusi. Že nezvládnete ani takovéhle základy a nechápete, v čem je problém, to mne překvapilo. Vaše hodnocení mých rad je mi tím pádem úplně jedno.

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #25 kdy: 30. 06. 2018, 21:12:27 »
Nemůžeš tu podmínku hodit do cyklu.
Nízkoúrovňové čtení nebo zápis z/do streamnů (soubory, sokety apod.) vždy může zpracovat menší množství dat, než bylo požadováno, proto se musí opakovat v cyklu. To snad vědí programátoři už ve školce.

Děti ve školce znají věc jako zacyklení. Ty ne?

Musíš testovat, zda návratová hodnota je větší jak 0 - jak píše @kvr kvr, pak teprve můžeš zkusit zapsat znova.
U toho nízkoúrovňového zápisu představuje chybu jen záporná hodnota. Je možné, že PHP to má zařízené tak, aby se vždy zapsal alespoň jeden bajt, a nula také znamená chybu, ale pak je vážná chyba v dokumentaci, že to tam není napsané.
Takže doporučuješ kód, který v případě, že dojde místo na disku, tak se zacyklí?

@andreaw.fean zvolil opačnou strategii, a při neúspěchu prostě končí - což je v pořádku.
V pořádku ovšem není, že končí chybou i v případě úspěšného (částečného) zápisu.
Furt lepší, než co navrhuješ ty.

Ty posixový funkce nefungují.
Jasně, vy jste expert na všechno a chyba je v Linuxu nebo jakou implementaci POSIXu myslíte. To sedí od někoho, kdo ani neví, jak zkopírovat data z jednoho souboru do druhého.

Sečteno a podtrženo problém je v tom, že tvá rada byla úplně špatná.
Že vám programování moc nejde jsem pochopil už v sousední diskusi. Že nezvládnete ani takovéhle základy a nechápete, v čem je problém, to mne překvapilo. Vaše hodnocení mých rad je mi tím pádem úplně jedno.
Když to říkáš.

.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #26 kdy: 30. 06. 2018, 21:14:07 »
Nemůžeš tu podmínku hodit do cyklu. Musíš testovat, zda návratová hodnota je větší jak 0 - jak píše @kvr kvr, pak teprve můžeš zkusit zapsat znova
Pokus o zápis nemusí zapsat všechna data, takže bežné a správné řešení je v cyklu zapisovat to, co zbývá zapsat, dokud není zapsáno všechno a pokud při zápisu aktuálního "kousku" dojde k chybě, tak cyklus přerušit. Co je na tom k nepochopení?

.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #27 kdy: 30. 06. 2018, 21:18:41 »
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í.

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #28 kdy: 30. 06. 2018, 21:19:57 »
Nemůžeš tu podmínku hodit do cyklu. Musíš testovat, zda návratová hodnota je větší jak 0 - jak píše @kvr kvr, pak teprve můžeš zkusit zapsat znova
Pokus o zápis nemusí zapsat všechna data, takže bežné a správné řešení je v cyklu zapisovat to, co zbývá zapsat, dokud není zapsáno všechno a pokud při zápisu aktuálního "kousku" dojde k chybě, tak cyklus přerušit. Co je na tom k nepochopení?
Nekonečný cyklus.

.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #29 kdy: 30. 06. 2018, 21:25:30 »
...dojde k chybě, tak cyklus přerušit.