una txt texto sobrescribir reemplazar manejo lineas linea leer especifica escribir ejemplos crear archivos archivo agregar c# performance file-io

c# - txt - Manera eficiente de eliminar una línea de un archivo de texto



reemplazar texto en archivo txt c# (8)

Necesito eliminar cierta línea de un archivo de texto. ¿Cuál es la forma más eficiente de hacer esto? El archivo puede ser potencialmente grande (más de un millón de registros).

ACTUALIZACIÓN: a continuación está el código que estoy usando actualmente, pero no estoy seguro de si es bueno.

internal void DeleteMarkedEntries() { string tempPath=Path.GetTempFileName(); using (var reader = new StreamReader(logPath)) { using (var writer = new StreamWriter(File.OpenWrite(tempPath))) { int counter = 0; while (!reader.EndOfStream) { if (!_deletedLines.Contains(counter)) { writer.WriteLine(reader.ReadLine()); } ++counter; } } } if (File.Exists(tempPath)) { File.Delete(logPath); File.Move(tempPath, logPath); } }


Dependiendo de lo que realmente cuenta como "eliminación", su mejor solución puede ser sobrescribir la línea ofensiva con espacios. Para muchos propósitos (incluido el consumo humano), esto equivale a borrar la línea directamente. Si la línea en blanco resultante es un problema, y ​​está seguro de que nunca eliminará la primera línea, puede agregar los espacios a la línea anterior sobrescribiendo también el CRLF con dos espacios.

(Basado en el comentario a la respuesta de Bork Blatt)


La forma más sencilla de hacer esto es probablemente la mejor, escriba el archivo completo en un nuevo archivo y escriba todas las líneas, excepto las que no desea.

Alternativamente, abra el archivo para acceso aleatorio.

Lea hasta el punto en que desea "eliminar" la línea. Omita más allá de la línea para eliminar, y lea esa cantidad de bytes (incluido CR + LF, si es necesario), escriba ese número de bytes sobre la línea eliminada, avance ambas ubicaciones por ese número de bytes y repita hasta el final del archivo.

Espero que esto ayude.

EDITAR - Ahora que puedo ver tu código

if (!_deletedLines.Contains(counter)) { writer.WriteLine(reader.ReadLine()); }

No funcionará, si es la línea que no quiere, aún quiere leerla , simplemente no la escriba . El código anterior no lo leerá ni lo escribirá. El nuevo archivo será exactamente el mismo que el anterior.

Quieres algo como

string line = reader.ReadLine(); if (!_deletedLines.Contains(counter)) { writer.WriteLine(line); }


Los archivos de texto son secuenciales, por lo que al eliminar una línea, tendrá que mover todas las líneas siguientes. Puede usar mapeo de archivos (una API Win32 a la que puede llamar a través de PInvoke) para hacer que esta operación sea menos dolorosa, pero seguramente debería considerar usar una estructura no secuencial para su archivo para marcar una línea como eliminada sin quitar realmente del archivo ... Especialmente si debería suceder con frecuencia.

Si recuerdo, la API de mapeo de archivos debe agregarse a .Net 4.


Si tiene que usar un archivo de texto y no puede cambiar a una base de datos, tal vez desee designar un símbolo extraño al principio de una línea para indicar "línea eliminada". Simplemente haga que su analizador ignore esas líneas, como líneas de comentarios en archivos de configuración, etc.

Luego, tenga una rutina periódica "compacta" como Outlook, y la mayoría de los sistemas de bases de datos, que vuelve a escribir todo el archivo, excluyendo las líneas eliminadas.

Me gustaría ir con la respuesta de Think Before Coding que recomienda una base de datos u otro archivo estructurado.


Lea su archivo en un diccionario en líneas no eliminables establezca el int en 0 en la línea que necesita marcar como eliminado. Set int to 1. Use un KeyValuePair para extraer las líneas que no necesitan borrarse y escríbalas en un nuevo archivo .

Dictionary<string, int> output = new Dictionary<string, int>(); // read line from file ... // if need to delete line then set int value to 1 // otherwise set int value to 0 if (deleteLine) { output[line] = 1; } else { output[line] = 0; } // define the no delete List List<string> nonDeleteList = new List<string>(); // use foreach to loop through each item in nonDeleteList and add each key // who''s value is equal to zero (0) to the nonDeleteList. foreach (KeyValuePair<string, int> kvp in output) { if (kvp.Value == 0) { nonDeleteList.Add(kvp.Key); } } // write the nondeletelist to the output file File.WriteAllLines("OUTPUT_FILE_NAME", nonDeleteList.ToArray());

Eso es.


En mi blog, comparé varios métodos de E / S de C # para determinar la forma más eficiente de hacer E / S de archivos. En general, es mejor utilizar las funciones de Windows ReadFile y WriteFile. La siguiente forma más rápida de leer archivos es a través de FileStream. Para obtener un buen rendimiento, lea los archivos en bloques a la vez en lugar de una línea a la vez y luego haga su propio análisis sintáctico. El código que puede descargar de mi blog le da un ejemplo sobre cómo hacer esto. También hay una clase C # que encapsula la funcionalidad de Windows ReadFile / WriteFile y es bastante fácil de usar. Ver mi blog para más detalles en:

http://designingefficientsoftware.wordpress.com/2011/03/03/efficient-file-io-from-csharp

Bob Bryan MCSD


try{ Scanner reader = new Scanner(new File("D:/seenu.txt")); System.out.println("Enter serial number:"); String sl1=bufRead.readLine(); System.out.print("Please Enter The ServerName:"); String name=bufRead.readLine(); System.out.println("Please Enter The IPAddress"); String ipa=bufRead.readLine(); System.out.println("Line Deleted."); PrintWriter writer = new PrintWriter(new FileWriter(new File("D:/user.txt")),true); //for(int w=0; w<n; w++) writer.write(reader.nextLine()); reader.nextLine(); while(reader.hasNextLine()) writer.write(reader.nextLine()); } catch(Exception e){ System.err.println("Enjoy the stack trace!"); e.printStackTrace(); }