PDA

Ver la versión completa : Escritura de ficheros en modo síncrono desde C



miq01
13/12/2005, 10:44
Por si interesa, y para que quede constancia:

Recordemos que el Linux de GP2X (no sé si es aplicable a cualquier Linux) accede a disco en modo asíncrono por defecto. Es decir, si por ejemplo una aplicación decide escribir algo a disco, en realidad se escribe en un buffer y Linux decide cuándo lo pasa realmente a disco. Esto puede provocar que ciertas operaciones de escritura no se realicen si, por ejemplo, apagamos la consola con la aplicación abierta y Linux aún no ha volcado el contenido del buffer en disco. Era el caso de DrMD (ya solucionado en la nueva versión), y también pasaba en Tilematch (a veces la tabla de puntuaciones máximas no se escribía).

Pues bien, a parte de la posibilidad de crear un script que fuerce este modo de escritura, tal como se explica en el tutorial sobre scripting (http://www.gp32spain.com/foros/showthread.php?t=25060), también se puede hacer desde C. ¿Cómo? Ejecutando la instrucción sync() (http://seth.positivism.org/man.cgi/2/sync) después de una llamada a fclose():

FILE* archivo = fopen(...);
fwrite(...);
fclose(archivo);
sync();
Puesto que sync() está en unistd.h, será necesario añadir

#include <unistd.h>
Por cierto, yo he probado otra alternativa, consistente en llamar a execl(...) para que ejecute el comando sync de bash al empezar la aplicación (y luego he probado lo mismo, pero justo antes de salir) pero no he conseguido que funcione.

D_Skywalk
13/12/2005, 15:28
Gracias Miq01, a ver si asi consigo hacer debug, por que mis aplicaciones siguen con la pantalla negra y no puedo debugear na :/

Un Saludo :)

WinterN
13/12/2005, 15:42
Gracias! Lo tendré en cuenta en mis programillas. :brindis:

oankali
13/12/2005, 16:07
Si al abrir el archivo con fopen() se utiliza el flag 'c' (commit flag), luego se puede utilizar fflush() para forzar la escritura del bufer en el disco sin tener que cerrar el archivo. La función es compatible ANSI y ya se encuentra en stdio.h.
Supongo que también funcionará para la GP2X.

miq01
13/12/2005, 20:20
Si al abrir el archivo con fopen() se utiliza el flag 'c' (commit flag), luego se puede utilizar fflush() para forzar la escritura del bufer en el disco sin tener que cerrar el archivo. La función es compatible ANSI y ya se encuentra en stdio.h.
Supongo que también funcionará para la GP2X.
Lo que he escrito en el primer mensaje lo he sacado de este hilo (http://www.gp32x.com/board/index.php?showtopic=23113&view=findpost&p=314255) de GP32x. Si lees, verás que alguien dice que fflush no hace exactamente eso y que no sirve para sincronizar. Pero bueno, lo del flag 'c' que comentas no sé si cambia el comportamiento.

oankali
13/12/2005, 21:50
Lo que he escrito en el primer mensaje lo he sacado de este hilo (http://www.gp32x.com/board/index.php?showtopic=23113&view=findpost&p=314255) de GP32x. Si lees, verás que alguien dice que fflush no hace exactamente eso y que no sirve para sincronizar. Pero bueno, lo del flag 'c' que comentas no sé si cambia el comportamiento.

Es interesante lo que pone, pero leyendo esto (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_fflush.asp) llego a la conclusión de que fflush() hace justamente lo que queremos y sin tener que cerrar el archivo, ni agregar una librearía.
Aunque acabo de ver que segun esto (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_fopen.2c_._wfopen.asp) el flag 'c' es una extensión de Microsoft o sea que en nuestro caso no hay que utilizarlo, pero fflush() sí que es estándar.

Si sync() funciona y fflush() no, pues utilizaremos sync() :)

miq01
14/12/2005, 04:03
Aunque acabo de ver que segun esto (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_fopen.2c_._wfopen.asp) el flag 'c' es una extensión de Microsoft o sea que en nuestro caso no hay que utilizarlo, pero fflush() sí que es estándar.
Si es de Microsoft, entonces mejor no usarlo... :)

Yo es que, además, soy de cerrar los archivos en cuanto puedo. Que sino siempre acabo dejándolos abiertos...

(_=*ZaXeR*=_)
14/12/2005, 04:22
Si al abrir el archivo con fopen() se utiliza el flag 'c' (commit flag), luego se puede utilizar fflush() para forzar la escritura del bufer en el disco sin tener que cerrar el archivo. La función es compatible ANSI y ya se encuentra en stdio.h.
Supongo que también funcionará para la GP2X.
Iba a decir precisamente lo mismo. Esto es algo que me jode, porque en mi facultad el fflush() como sino existiera para los profesores, y despues te mandan hacer un algoritmo que escriba en un fichero rellenando una plantilla que ellos dan (payasos, estupidos) y no te cabe el algortimo que has diseñado con el que ellos han hecho. Y despues suspendes el examen y despues te cagas en ellos y despues... MUERTE A LAS PLANTILLAS EN LOS EXAMENES, ASI NO SE EVALUA SI UN TIO SABE PROGRAMAR, ASI SE EVALUA SI UN TIO ACIERTA UNA QUINIELA DE 15 :canon2: