2009-07-20 12 views
15

Quiero eliminar ciertas líneas en un archivo e insertar ciertas líneas en el mismo archivo en función de si ciertas partes de la línea coinciden con una cadena especificada. ¿Hay alguna forma de hacerlo sin usar un archivo temporal para copiar el contenido, etc.?Eliminar una línea de un archivo en C Idioma

Respuesta

27

El problema es que un archivo es (esencialmente) una matriz de bytes en el disco (o cualquier otro sustrato físico, pero, ¡de todos modos!), Y "una línea" puede tomar un número variable de bytes; así que insertar o quitar líneas (a menos que siempre esté reemplazando rigurosamente una línea con otra línea de exactamente la misma longitud en bytes) requeriría "desplazar" todo el resto del archivo "hacia arriba" o hacia "abajo" por la diferencia en bytes ... que puede ser una operación extremadamente onerosa (ya que el resto del archivo puede ser gigabytes incluso si solo está cambiando la longitud de una línea por 1 byte hacia el principio del archivo).

Por lo tanto, estas operaciones pueden ser increíblemente onerosas y, por lo tanto, nunca se ofrecen como primitivas en CUALQUIER idioma que soporte archivos con longitud de línea variable (C, Python, Java, C++, Ruby o CUALQUIER otro lenguaje similar). Es extremadamente improbable que realmente deba pagar un costo potencialmente sin consolidar en cuanto a rendimiento Y riesgo (un sistema o un bloqueo de disco durante el "cambio" de GB o los datos hacia arriba o hacia abajo pueden destruir la usabilidad de su archivo completo y enorme), cuando La técnica perfectamente simple, adecuada, rápida, segura y razonable que está tratando de evitar tiene básicamente desventajas CERO (por lo que está lejos de ser evidente ¿POR QUÉ está tratando de evitarlo?).

Utilice un archivo de resultados diferente del archivo fuente, cuando termine el archivo de resultados sobre el archivo fuente (una operación atómica en la mayoría de los sistemas si está dentro del mismo sistema de archivos), y realmente tiene El mejor de los mundos posibles.

3

No puede "cortar" fácilmente una sección de un archivo en el lugar. Siempre haces una copia temporal en alguna parte. Esto no es una cosa C; es cierto para cualquier idioma

Puede mmap el archivo, y luego cuando encuentre la línea que desea borrar, puede memcpy todo después de ella en la ubicación del inicio de la línea. Preguntaría qué tan eficiente sería eso; el archivo temporal puede ser más rápido.

+0

El el archivo temporal es mucho * más seguro *. – RBerteig

+0

De acuerdo, esta no sería mi primera opción ... o de hecho, cualquier opción. Es lo único que se me ocurre que podría satisfacer la solicitud. Este enfoque es posiblemente más seguro (no hay problemas de permisos de archivos temporales), pero acepto que se corromperá el archivo en caso de que se produzca algún error. –

0

Si el archivo no es lo suficientemente grande para procesar en la RAM, puede usar la lista de cadenas enlazadas, donde cada nodo representa una línea, que es un nodo de la lista vinculada creada en base al carácter '\ n' y luego puede insertar operaciones y eliminar operaciones en la lista vinculada según sea necesario y luego puede sobrescribir en el mismo archivo usando la lista vinculada.

Por ejemplo, mytext.txt

Este es un archivo de prueba

Una línea tiene que ser añadido por encima de

Esta línea tiene que ser eliminado

Ahora cuando se crea una lista enlazada de archivo de arriba, sería como

[Este es un archivo de prueba] -> [Se debe agregar una línea arriba] -> [Esta línea tiene que ser eliminado] -> [NULL]

Insertar Operación cambiará la lista enlazada a

[Este es un archivo de prueba] -> [Esta es una nueva línea] -> [A la línea tiene que ser añadido más arriba] -> [Esta línea tiene que ser eliminado] -> [NULL]

operación de borrado cambiará la lista enlazada a

[Este es un archivo de prueba] - > [Thi s es una nueva línea] -> [Una línea tiene que añadir más arriba] -> [NULL]

Ahora se puede escribir la lista enlazada al archivo MyText.txt con 'n \' carácter en el final de cada nodo

el archivo final sería, MyText.txt

Este es un archivo de prueba

Esta es una nueva línea

Una línea tiene que ser añadido por encima de

Cuestiones relacionadas