Permalänk

fclose() i Unix alt. Windows

Hej,
Har funderingar på hur man stänger en fil i windows alt. Unix.
Slentrianmässigt använder jag FILE *p samt sen fclose(p) men har problem med detta i Linux ibland.
Så jag har (utan att ha grottat ner mig i detaljerna) använt mig av sekvensen:

fflush(p);
fsync(fileno(p));
fclose(p):

Detta har räddat applikationen i bland annat Linux. Men vad är rätt sätt? För min del känns det som tårta-på-tårta.

Funktionerna används både i Windows-miljö samt även i Linux.
fflush/fsync behövs väl inte när man LÄSER en fil?

Tacksam för tips.

Permalänk
Medlem

fclose() ska anropa fflush implicit också, möjligen varierande beroende på flaggor för strömmen. Har du kollat om du får någon errorkod efter fclose anropet?

fsync ser till att buffers i kernel skrivs till den fysiska disken. Jag har aldrig använt den själv, så har inte mer insikt än så. Misstänker att om filsystemet eller disken tvingas att monteras bort omgående kan data gå förlorad.

Har du någon mer information om vad som går fel på linux? Du nämner att applikationen räddas av de extra fflush och fsync, vad händer utan de funktionsanropen?

Skickades från m.sweclockers.com

Permalänk
Skrivet av waegogin:

fclose() ska anropa fflush implicit också, möjligen varierande beroende på flaggor för strömmen. Har du kollat om du får någon errorkod efter fclose anropet?

fsync ser till att buffers i kernel skrivs till den fysiska disken. Jag har aldrig använt den själv, så har inte mer insikt än så. Misstänker att om filsystemet eller disken tvingas att monteras bort omgående kan data gå förlorad.

Har du någon mer information om vad som går fel på linux? Du nämner att applikationen räddas av de extra fflush och fsync, vad händer utan de funktionsanropen?

Skickades från m.sweclockers.com

Jag kan inte svara på om fclose i detta fall returnerar ERR. Jag gjorde det säkert i ett tidigare proj men minns inte resultatet. Jag ska kolla det när jag får igång systemet igen (idag).

Vad jag vet NU är att fsync() direkt efter en fflush stänger en fil korrekt som tidigare växte okontrollerat på en Raspberry. Då stängdes filen med enbart fflush och fclose. Denna lösning är dock inte testat i en windowsmiljö. I min fantasivärld tror man att nån miljöväxel gör nåt med kompileringen. Det är detta jag vill reda ut.

Permalänk
Medlem

Låter knepigt, det enda jag kan föreställa mig just nu skulle vara om massor av data ligger och väntar på att skrivas, och av någon anledning avbryts iom. anropet till fsync. Har själv märkt av att i Linux så är buffers för disk I/O ganska stora, men jag märkte det när jag flyttade filer till en USB- disk. Att kopiera filen gick väldigt fort, men när jag skulle avmontera disken så behövde jag vänta säker 5 minuter (ett par gb stor fil eller så). Säkert jag som använt fel flaggor vid montering från första början.

Har dålig koll på miljöväxlar för C standardbiblioteket vid kompilering, måste nog låta någon mer erfaren ta över.

Skickades från m.sweclockers.com

Permalänk
Skrivet av waegogin:

Låter knepigt, det enda jag kan föreställa mig just nu skulle vara om massor av data ligger och väntar på att skrivas, och av någon anledning avbryts iom. anropet till fsync. Har själv märkt av att i Linux så är buffers för disk I/O ganska stora, men jag märkte det när jag flyttade filer till en USB- disk. Att kopiera filen gick väldigt fort, men när jag skulle avmontera disken så behövde jag vänta säker 5 minuter (ett par gb stor fil eller så). Säkert jag som använt fel flaggor vid montering från första början.

Har dålig koll på miljöväxlar för C standardbiblioteket vid kompilering, måste nog låta någon mer erfaren ta över.

Skickades från m.sweclockers.com

Vad jag (tror) jag vet är att fsync() gör nåt med buffers som ligger närmare hårdvaran. Det är kanske så att fflush tsm med fclose inte väntar tills hårdvaran är klar? Fsync tar hand om den biten innan fclose. Det är spekulering och jag tror jag blir rättad i kväll. Jag tror dessutom att det är skillnad mellan en stream och dessa "filnummer" som fsync ska ha. Windows alt. Unix?

Permalänk
Medlem
Skrivet av Sweedland:

Vad jag (tror) jag vet är att fsync() gör nåt med buffers som ligger närmare hårdvaran. Det är kanske så att fflush tsm med fclose inte väntar tills hårdvaran är klar? Fsync tar hand om den biten innan fclose. Det är spekulering och jag tror jag blir rättad i kväll. Jag tror dessutom att det är skillnad mellan en stream och dessa "filnummer" som fsync ska ha. Windows alt. Unix?

fflush() "flushar" buffrarna från userspace till kärnan. fsync() i sin tur flushar data från kärnan till det fysiska lagringsmediet (ifall du håller på med filer). fclose() anropar implicit fflush() men inte fsync(). Så om du vill att datat ska skrivas till disk så snabbt som möjligt bör du anropa fsync(). Om man jobbar mot t.ex. usb-minnen eller mmc-kort, är det inte säkert att datat är skrivet ändå när fsync() returnerar, eftersom dom i sin tur innehåller egna buffrar, men det är det bästa man kan göra ur ett programmerarperspektiv.

Permalänk
Skrivet av pelleplu:

fflush() "flushar" buffrarna från userspace till kärnan. fsync() i sin tur flushar data från kärnan till det fysiska lagringsmediet (ifall du håller på med filer). fclose() anropar implicit fflush() men inte fsync(). Så om du vill att datat ska skrivas till disk så snabbt som möjligt bör du anropa fsync(). Om man jobbar mot t.ex. usb-minnen eller mmc-kort, är det inte säkert att datat är skrivet ändå när fsync() returnerar, eftersom dom i sin tur innehåller egna buffrar, men det är det bästa man kan göra ur ett programmerarperspektiv.

Korrekt. Filhantering.
Som du beskriver det så har jag tolkat tidigare svar också. Det är en bekräftelse.

På mig låter det som om det vore en två-stegsraket. fflush() först som fraktar datat från UserSpace till HW. Sen fsync() som skickar från HW till mediet. I det läget verkar filen bli korrekt skriven och inte blir galen och blir ist för 44 byten blev den 44 Meg.