• Viernes 8 de Noviembre de 2024, 17:35

Autor Tema:  Truncar Un Archivo  (Leído 4888 veces)

Forly

  • Nuevo Miembro
  • *
  • Mensajes: 21
    • Ver Perfil
Truncar Un Archivo
« en: Sábado 23 de Abril de 2005, 20:17 »
0
Hola a todos:

Les agradecería si alguien me puede informar cómo puedo hacer para truncar un archivo a partir de un registro determinado.

Yo lo intenté escribendo en esa posición el ASCII 26 (EOF) pero no resultó.

Existe algina manera?...

Uso el Turbo C++ 3.0.

No quiero generar un archivo auxiliar sino trabajar sobre el original.

Desde ya muchas gracias por leer mi consulta.

carmamezo

  • Miembro MUY activo
  • ***
  • Mensajes: 232
    • Ver Perfil
Re: Truncar Un Archivo
« Respuesta #1 en: Lunes 25 de Abril de 2005, 10:02 »
0
Puedes leer el archivo completamente cargando todos los registros en memoria, cerrar el archivo, deshacerte de aquellos registros que no desees y sobreescribir el archivo original con los registros que te interesen, abriéndolo para escribir de nuevo.
También puedes leer el archivo hasta donde te interese, o sólo aquellos registros que quieras conservar y luego sobreescribir el archivo sólo con los registros leidos.
Espero que te sirva la respuesta, saludos.
No hay tonto más molesto que el ingenioso.

Forly

  • Nuevo Miembro
  • *
  • Mensajes: 21
    • Ver Perfil
Re: Truncar Un Archivo
« Respuesta #2 en: Martes 26 de Abril de 2005, 20:47 »
0
Gracias Amigo por tu ayuda, pero el caso es que mi intención no es usar memoria, ya que con un archivo muy voluminoso esto no resultaría.

Mi propuesta es poner un END OF FILE en el byte posterior al último registro que quiero conservar, pero justamente esto es lo que no puedo hacer.

Si el C/C++ es capaz de leer una marca de EOF, la lógica dice que si la corro de lugar, el fin de archivo cambiaría su posición.

Este es el QUID.

De todos modos te agradezco tu preocupación.

Te mando un abrazo.

rir3760

  • Miembro activo
  • **
  • Mensajes: 37
    • Ver Perfil
Re: Truncar Un Archivo
« Respuesta #3 en: Miércoles 27 de Abril de 2005, 00:06 »
0
Utilizando solo C estandard no se puede ya que EOF no es un caracter que se lea de un stream sino el estado del stream.

Para realizar la operacion necesitas revisar la documentacion sobre el API de tu sistema operativo para averiguar si esta (el API) expone una funcion que realize la operacion que requieres.

Un saludo
The capacity to learn is a gift; The ability to learn is a skill; The willingness to learn is a choice. -- Rebec of Ginaz

carmamezo

  • Miembro MUY activo
  • ***
  • Mensajes: 232
    • Ver Perfil
Re: Truncar Un Archivo
« Respuesta #4 en: Miércoles 27 de Abril de 2005, 10:06 »
0
Hola de nuevo....
He estado echando un vistazo a la msdn, y he encontrado una funcion que igual hace lo que necesitas, pertenece a la API de windows...  Si estás programando sobre otro SO no te servirá...  <_<
Te mando un ejemplo en el que creo un archivo de 100 estructuras, todas iguales, y luego lo trunco a partir de una estructura concreta, sin usar memoria ni archivos auxiliares:
Código: Text
  1.  
  2. #include <windows.h>
  3. #include <stdio.h>
  4. #include <io.h>
  5. #include <fcntl.h>
  6. #include <sys/stat.h>
  7.  
  8.  
  9. typedef struct
  10. {
  11.   int a;
  12.   double b;
  13.   char c[50];
  14. }datos;
  15.  
  16.  
  17. void crea_fich(FILE *pf)
  18. {  
  19.   int i;
  20.   datos uno;
  21.  
  22.   uno.a=3;
  23.   uno.b=5.5;
  24.   strcpy(uno.c,"Hola mundo");
  25.   for(i=0;i<100;i++)
  26.   {
  27.     fwrite(&uno,sizeof(datos),1,pf);
  28.   }
  29. }
  30.  
  31.  
  32. void main()
  33. {
  34.   FILE *pf;
  35.   int n_reg,op,fh,res;
  36.  
  37.   if((pf=fopen("datos.dat","w"))==NULL)
  38.   {
  39.     printf("Error abriendo archivo");
  40.     return;
  41.   }
  42.  
  43.   crea_fich(pf);
  44.  
  45.   //calcular el numero de registros que hay en el ficrero: 100
  46.   fseek(pf,0L,SEEK_END);
  47.   n_reg=ftell(pf)/sizeof(datos);
  48.   printf("\n\tNumero de registros en el fichero: %d",n_reg);
  49.   printf("\n\tNumero de bytes: %d",n_reg*sizeof(datos));
  50.  
  51.   //seleccionar a partir de que registro se truncará el fichero
  52.   printf("\n\n\tSelecciona numero de registro a partir\n\t del cual se truncara: ");
  53.   scanf("%d",&op);
  54.   op*=sizeof(datos);//el tamaño debe ser en bytes
  55.  
  56.   fclose(pf);
  57.   //abrir el fichero
  58.   if((fh=_open("datos.dat",_O_RDWR,_S_IWRITE ))!=-1)
  59.   {
  60.     //cambiar el tamaño del archivo
  61.     if((res=_chsize(fh,(long)op))!=0)
  62.     {
  63.       printf("\n\tERROR no se ha podido cambiar el tamano");
  64.       fflush(stdin);
  65.       getchar();
  66.       return;
  67.     }
  68.     printf("\n\tEl archivo ha sido truncado!!!");
  69.     _close(fh);
  70.  
  71.     if((pf=fopen("datos.dat","r"))==NULL)
  72.     {
  73.       printf("Error abriendo archivo");
  74.       fflush(stdin);
  75.       getchar();
  76.       return;
  77.     }
  78.     fseek(pf,0L,SEEK_END);
  79.     n_reg=ftell(pf)/sizeof(datos);
  80.     printf("\n\tNumero de registros en el fichero ahora: %d",n_reg);
  81.     fclose(pf);
  82.  
  83.   }
  84.   fflush(stdin);
  85.   printf("\n\n\n\tPulsa <enter> para finalizar.");
  86.   getchar();
  87.  
  88. }
  89.  
  90.  
Espero que te sirva de ayuda... Un saludo  :lightsabre:
No hay tonto más molesto que el ingenioso.

Forly

  • Nuevo Miembro
  • *
  • Mensajes: 21
    • Ver Perfil
Re: Truncar Un Archivo
« Respuesta #5 en: Viernes 29 de Abril de 2005, 20:49 »
0
Gracias Amigos!!!

En verdad les agradezco su preocupación, pero yo necesito hacerlo en ANSI C o en un C++ portable que sirva para cualquier sistema operativo.

Voy a ver si le encuentro la salida por el lado del ASSEMBLER.

Intentaré hacer una función en ASM y la llamaré desde C/C++.

Si tengo éxito les mando una copia.

Un abrazo.

:think:

pitukilloloco

  • Miembro MUY activo
  • ***
  • Mensajes: 104
    • Ver Perfil
Re: Truncar Un Archivo
« Respuesta #6 en: Martes 3 de Mayo de 2005, 02:03 »
0
Eso que deseas hacer no los vas a resolver con una sóla lectura en alguna posición del archivo, ya que cuando escribes en el disco usando las funciones estándar, éstas no sólo escriben los bytes de que se compone el archivo, sino también información relacionada a los sectores físicos del disco en donde se encuentran estos bytes y la manera en cómo se ligan estos sectores para formar el archivo, así como el número de bytes. De manera que, ¿qué crees que pasaría si con una simple instrucción como poner el EOF en alguna parte del archivo que quieres truncar pudieras dividirlo? el nombre que tiene ese archivo sería el de la primera parte ¿cómo sabría el sistema operativo qué nombre ponerle a la segunda? Y en caso de que desecharas la segunda parte ¿cómo sabría el sistema operativo, que los sectores físicos del disco en donde está la segunda parte desechada, ya están listos para usarse por otro archivo? Dices que quieres que sea portable a varios sistemas operativos pero ya al querer usar ensamblador te estás contradiciendo porque el ensamblador es propio de cada máquina. Si quieres que sea portable tienes que usar necesariamente las librerías estándar que manejen archivos y éstas, por lo que yo sé, son las que se encuentran en stdio.h Al poner una respuesta en este foro no pretendo criticar sino tratar de proponer una sólución pero por más que le pienso no hallo la manera en que puedas hacer un programa portable  para lo que quieres sin generar otro archivo auxiliar.  El antiguo sistema operativo MS-DOS usaba un sistema de archivos que llamaba FAT16. En éste había una parte del sistema en donde guardaba los nombres de los directorios y archivos, y otra en donde estaba la información de los clústeres (grupos de sectores físicos de disco) que componían cada archivo. En este sistema operativo uno podía hacer un programa en C que escribiera directamente en esas partes. Aquí si se podría hacer eso que tu quieres pero de ninguna manera portable. Para hacer esto mismo en los sistemas de archivos de los sistemas operativos actuales (FAT32, NTFS, de linux, de Unix, etc.) tendrías que conocer la forma de hacerlo y eso suponiendo que se pueda hacer ya que en estos sistemas no te permiten manejar directamente el sistema de archivos, manejo que está reservado al kernel de cada SO. Si encuentras la forma de hacerlo te agradecería publicaras tu respuesta. Disculpa el no poder ayudarte.