2009-02-25 20 views
12

Estoy usando fopen fseeko64 ftello64 ​​fclose etc. para operar en un archivo.Truncar archivo

¿Cómo puedo truncar un archivo? Sé que no hay una forma estándar de hacerlo en C. Lo único que quiero es una forma que funcione en cualquier plataforma win32. Estoy usando mingw gcc para compilar.

Tenga en cuenta: quise truncar el tamaño del archivo a un tamaño específico, no hacerlo de 0 tamaño. Y usar un truco como copiar parte en otro archivo y eliminar/renombrar no es apropiado.

+0

¿Quisiste decir truncar en una posición específica o truncar a un archivo vacío? – paxdiablo

+0

posible ** duplicado ** de ** [¿Cómo truncar un archivo en C?] (Http://stackoverflow.com/a/873653/2432317) ** –

Respuesta

5

Si desea truncar el archivo de tamaño cero, puede fopen con el "w" bandera:

FILE *fh = fopen("file.txt","w"); 
if (fh != NULL) fclose(fh); 

para truncar a un tamaño específico en C estándar, puede hacer esto con una transferencia/cambiar el nombre de la solución, algo así como:

FILE *finp = fopen ("inp.txt", "rb");  // should check for NULLs 
FILE *fout = fopen ("out.txt", "wb"); 

size_t sz = 100000;       // 100,000 bytes 
char *buff = malloc (sz);     // should check for NULL 

sz = fread (buff, 1, sz, fin);    // should check for errors 
fwrite (buff, 1, sz, fout); 

free (buff); 

fclose (fin); 
fclose (fout); 

rename ("out.txt", "inp.txt);    // should check for error 

Por supuesto, si usted tiene acceso a las cabeceras de Win32 y Libra (y creo que MinGW le da esto), puede usar SetEndOfFile(), ya que lo hace en su lugar, en lugar de tener que crear un nuevo archivo y luego cambiarle el nombre.

Eso significa usar E/S de archivo basado en el controlador de Windows en lugar de C FILE*, pero, si se limita a Windows de todos modos, puede que no importe. Si desea la portabilidad, por otro lado, necesitará una solución basada en C estándar, como la solución de transferencia/cambio de nombre anterior.

+1

¿Por qué está usando un puntero a un solo carácter? Puede usar fgetc() y fputc() y simplemente usar un no puntero (o incluso una variable): for (int i = 0; i <100000; i ++) fputc (fgetc (fin), fout); –

+0

Lo que daría como resultado 100.000 veces más llamadas a funciones :-) – paxdiablo

+0

Ah, hubo algunos errores de lectura. Lo siento. (Sin embargo, no creo que 100000 fgetc() s y fputc() s realmente lleven tanto tiempo.) –

17

SetEndOfFile()

obtener un identificador para el archivo con acceso de escritura, establecer el puntero de archivo, a continuación, llamar SetEndOfFile().

-Adam

+1

Desafortunadamente, esto no explica cómo convertir el valor FILE * que el OP tiene en una MANIJA adecuada para pasar a SetEndOfFile() – Malvineous

+0

Además de lo que ya fue [mencionado en el comentario] (http://stackoverflow.com/questions/584639/truncate-file#comment9468490_584647) por [@Malvineous] (http://stackoverflow.com/users/308237/malvineous) ... Me gustaría señalar que está apuntando a una función *** C++ ***, mientras que OP preguntó por *** C *** y explícitamente etiquetó la pregunta con *** C *** en consecuencia. –

1

Como ya se mencionó, puede utilizar fopen() con el indicador "w" como:

FILE *f = fopen("file.txt", "w"); 

Además, si ya se ha abierto el archivo, puede utilizar la función freopen(), de nuevo con la bandera "w":

FILE *f = fopen("file.txt", "r"); //initial fopen() call 
... 
f = freopen("file.txt", "w", f); //reopens "file.txt" and truncates it 

http://www.cplusplus.com/reference/clibrary/cstdio/freopen.html

EDITAR: Después de ver que has editado tu OP, no volveré a publicar lo que Pax y Adam Davis ya han dicho. Además, confirmaré lo que dijo Pax, que MinGW le da acceso a los encabezados de Win32.

4

Para las operaciones de archivo basadas en ARCHIVOS, use _fileno() y _chsize_s() para cambiar el tamaño de un archivo.

int changesize(FILE *fp, __int64 size) 
{ 
    int filedes = _fileno(fp); 
    return _chsize_s(filedes, size); 
} 

Una versión truncada se puede escribir mediante la validación de que el tamaño proporcionado es menor que el tamaño actual del archivo, como _chsize_s() van a truncar o ampliar el tamaño de un archivo - ver http://msdn.microsoft.com/en-us/library/whx354w1(VS.80).aspx.

+0

Suponiendo que tiene acceso al tiempo de ejecución de Microsoft. –