¿Cómo leo una línea específica en un archivo de texto?

Dado un archivo de texto, ¿cómo voy a leer una línea arbitraria y nada más en el archivo?

Diga, tengo un archivo test.txt. ¿Cómo voy a leer la línea número 15 en el archivo?

Todo lo que he visto es material que consiste en almacenar todo el archivo de texto como una matriz de cadenas y luego usar el valor del número de línea como el número de cadena para usar desde la matriz … pero hay algunas complicaciones: el archivo de texto es enormemente grande y la máquina que la aplicación que estoy codificando no es exactamente un sistema de primera categoría. La velocidad no es la principal prioridad, pero definitivamente es un problema importante.

¿Hay alguna forma de leer SOLAMENTE una línea específica de un archivo de texto y almacenar el resultado como una cadena?

Gracias por sus respuestas: el archivo está estructurado por KINDA. Tiene 25 líneas de información y luego X líneas de números, pero la línea 17 de los primeros 25 tiene el valor de X.

Pero luego, hay 1 línea en blanco y se repite todo como un segundo registro en el archivo y X puede tener un valor diferente para cada registro.

Lo que quiero hacer es leer y almacenar las primeras 25 líneas como valores independientes y luego almacenar las siguientes X (generalmente alrededor de 250) líneas como una matriz. Luego voy a almacenarlo en una base de datos SQL y repetir con el siguiente registro hasta llegar al registro Y th (el número de registros en el archivo está en la línea 3)

EDIT 2 : Bien, creo que he llegado a una solución basada en una combinación de las respuestas de tus alls.

Voy a leer las primeras 25 líneas y almacenarlas como una matriz. Copiaré los contenidos pertinentes de la matriz a las variables locales y luego borraré las primeras 25 líneas. Luego, puedo usar la información para almacenar las siguientes líneas X (el valor del elemento 13 en la matriz) como una matriz, serializarla, almacenarla en una base de datos y luego eliminar las líneas que acabo de leer.

Entonces podría repetir el proceso para cada registro subsiguiente.

Por supuesto, esto se basa en una suposición que estoy haciendo, que para ser honesto, no estoy seguro de que sea cierto. ¿Es posible eliminar las primeras n líneas de un archivo de texto desde C # sin tener que leer todo y volver a escribir sin las primeras n líneas?

.NET 4.0 editar

Desde .NET 4.0, es posible acceder directamente a una sola línea de un archivo. Por ejemplo, para acceder a la línea 15:

 string line = File.ReadLines(FileName).Skip(14).Take(1).First(); 

Esto devolverá solo la línea requerida


Como no puede predecir la ubicación (¿puede usted?) De la línea i-ésima en el archivo, también deberá leer todas las líneas anteriores. Si el número de línea es pequeño, esto puede ser más eficiente que el método ReadAllLines .

 string GetLine(string fileName, int line) { using (var sr = new StreamReader(fileName)) { for (int i = 1; i < line; i++) sr.ReadLine(); return sr.ReadLine(); } } 

Si cada línea tiene una longitud fija, puede abrir una secuencia a su alrededor, buscar (bytes por línea) * n en el archivo y leer su línea desde allí.

 using( Stream stream = File.Open(fileName, FileMode.Open) ) { stream.Seek(bytesPerLine * (myLine - 1), SeekOrigin.Begin); using( StreamReader reader = new StreamReader(stream) ) { string line = reader.ReadLine(); } } 

Alternativamente, puede usar StreamReader para leer líneas hasta que encuentre la que desea. De esa manera es más lento, pero sigue siendo una mejora sobre la lectura de cada línea.

 using( Stream stream = File.Open(fileName, FileMode.Open) ) { using( StreamReader reader = new StreamReader(fileStream) ) { string line = null; for( int i = 0; i < myLineNumber; ++i ) { line = reader.ReadLine(); } } } 

Desafortunadamente no hay. En el nivel bruto, los archivos no funcionan en función del número de línea. En cambio, trabajan en una posición / compensación. El sistema de archivos raíz no tiene concepto de líneas. Es un concepto agregado por componentes de nivel superior.

Entonces no hay forma de decirle al sistema operativo, por favor abra el archivo en la línea blah. En su lugar, debe abrir el archivo y omitir el conteo de nuevas líneas hasta que haya pasado el número especificado. Luego, almacene el siguiente conjunto de bytes en una matriz hasta que llegue a la siguiente línea nueva.

A menos que tenga líneas de tamaño fijo, necesita leer cada línea hasta que llegue a la línea que desea. Aunque no necesita almacenar cada línea, simplemente deséchela si no es la línea que desea.

Editar:

Como se mencionó, también sería posible buscar en el archivo si las longitudes de línea fueran predecibles, es decir, podría aplicar alguna función determinista para transformar un número de línea en una posición de archivo.

Como dijo Mehrdad, no puedes buscar la n-ésima línea sin leer el archivo. Sin embargo, no es necesario que almacene todo el archivo en la memoria, solo descarte los datos que no necesita.

 string line; using (StreamReader sr = new StreamReader(path)) for (int i = 0; i<15; i++) { line = sr.ReadLine(); if (line==null) break; // there are less than 15 lines in the file } 

LEA CINCO LÍNEAS CADA VEZ, simplemente ponga su statement en la statement if, eso es todo

  String str1 = @"C:\Users\TEMP\Desktop\StaN.txt"; System.IO.StreamReader file = new System.IO.StreamReader(str1); line = file.ReadLine(); Int32 ctn=0; try { while ((line = file.ReadLine()) != null) { if (Counter == ctn) { MessageBox.Show("I am here"); ctn=ctn+5; continue; } else { Counter++; //MessageBox.Show(Counter.ToString()); MessageBox.Show(line.ToString()); } } file.Close(); } catch (Exception er) { } 

Si las líneas son todas de una longitud fija, puede usar el método Seek de una secuencia para moverse a la posición de inicio correcta.

Si las líneas son de una longitud variable, sus opciones son más limitadas.

Si se trata de un archivo que solo usará una vez y luego descartará, entonces será mejor que lo lea y trabaje con él en memeory.

Si se trata de un archivo que mantendrá y leerá desde algo más que escribir, puede crear un archivo de índice personalizado que contenga las posiciones iniciales de cada línea. Luego usa ese índice para obtener tu posición de búsqueda. El proceso de creación del archivo de índice consume muchos recursos. Cada vez que agregue una nueva línea al archivo necesitará actualizar el índice, por lo que el mantenimiento se convierte en un tema no trivial.

Puede leer línea por línea para no tener que leer todo de una vez (probablemente en absoluto)

 int i=0 while(!stream.eof() && i!=lineNum) stream.readLine() i++ line = stream.readLine() 

Si su archivo contiene líneas con diferentes longitudes y necesita leer líneas a menudo y necesita leerlas rápidamente, puede hacer un índice del archivo leyéndolas una vez, guardando la posición de cada nueva línea y luego cuando necesite leer una línea , busque la posición de la línea en su índice, busque allí y luego lea la línea.

Si agrega nuevas líneas al archivo, puede agregar un índice de nuevas líneas y no necesita volver a indexarlo. Aunque si su archivo cambia en alguna parte de una línea que ya ha indexado, entonces tiene que reindexar.

Si bien no puede buscar una línea enésima directamente en un archivo no simétrico sin leer datos en el archivo (porque necesita contar cuántas líneas ha progresado en el archivo) puede contar los saltos de línea hasta que llegue al línea que desea que ocupa la menor cantidad de memoria y probablemente tenga el mejor rendimiento.

Esto va a ser más eficiente en cuanto a la memoria que leer todo en una matriz, ya que solo se leerá en el archivo hasta que llegue al final del archivo o al número de línea (lo que ocurra primero). Está lejos de ser perfecto, pero probablemente se adapte a sus necesidades:

 string line15 = ReadLine(@"C:\File.csv", 15); public string ReadLine(string FilePath, int LineNumber){ string result = ""; try{ if( File.Exists(FilePath) ){ using (StreamReader _StreamReader = new StreamReader(FilePath)){ for (int a = 0; a < LineNumber; a++) { result = _StreamReader.ReadLine(); } } } }catch{} return result; } 

Tratado y probado. Es tan simple como sigue:

 string line = File.ReadLines(filePath).ElementAt(actualLineNumber - 1); 

Siempre que tengas un archivo de texto, esto debería funcionar. Más tarde, dependiendo de qué datos espere leer, puede lanzar la cadena en consecuencia y usarla.

Una variacion. Produce un error si el número de línea es mayor que el número de líneas.

 string GetLine(string fileName, int lineNum) { using (StreamReader sr = new StreamReader(fileName)) { string line; int count = 1; while ((line = sr.ReadLine()) != null) { if(count == lineNum) { return line; } count++; } } return "line number is bigger than number of lines"; } 
  if (File.Exists(fpath)) { var data = File.ReadLines(fpath); Console.WriteLine(data.ToArray()[14]); } 

Última respuesta, pero vale la pena.

Debe cargar las líneas en una matriz o listar el objeto donde cada línea se asignará a un índice, luego simplemente llame a cualquier rango de líneas por su índice para el ciclo.

La solución es bastante buena, pero hay un consumo de memoria en el medio.

pruébalo … Vale la pena