txt texto separado reemplazar recursos por net lineas linea leer las escribir contar como comas archivos archivo agregar c# .net file-handling

separado - reemplazar texto en archivo txt c#



¿Cómo leer el archivo de texto por un personaje particular separador de línea? (11)

Lectura de un archivo de texto usando el lector de flujo.

using (StreamReader sr = new StreamReader(FileName, Encoding.Default)) { string line = sr.ReadLine(); }

Quiero forzar que el delimitador de línea sea /n not /r . Entonces, ¿cómo puedo hacer eso?


Aunque dijiste "Usar StreamReader", ya que también dijiste "Mi caso, el archivo puede tener toneladas de registros ...", recomendaría probar SSIS. Es perfecto para lo que estás tratando de hacer. Puede procesar archivos muy grandes y especificar fácilmente los delimitadores de líneas / columnas.


De acuerdo con la documentación:

http://msdn.microsoft.com/en-us/library/system.io.streamreader.readline.aspx

Una línea se define como una secuencia de caracteres seguida de un avance de línea ("/ n"), un retorno de carro ("/ r"), o un retorno de carro seguido inmediatamente de un avance de línea ("/ r / n").

De manera predeterminada, el método StreamReader ReadLine reconocerá una línea por ambos / cualquiera / n o / r


Esta es una mejora de la respuesta Sovemp. Lo siento, me hubiera gustado comentar, aunque mi reputación no me permite hacerlo. Esta mejora aborda dos problemas:

  1. la secuencia de ejemplo "text / rtest / r / n" con el delimitador "/ r / n" también eliminaría la primera "/ r" que no está prevista.
  2. cuando los últimos caracteres en el flujo son iguales al delimitador, la función devolvería erróneamente una cadena incluyendo delimitadores.

    using System; using System.IO; using System.Collections.Generic; internal static class StreamReaderExtensions { public static IEnumerable<string> ReadUntil(this StreamReader reader, string delimiter) { List<char> buffer = new List<char>(); CircularBuffer<char> delim_buffer = new CircularBuffer<char>(delimiter.Length); while (reader.Peek() >= 0) { char c = (char)reader.Read(); delim_buffer.Enqueue(c); if (delim_buffer.ToString() == delimiter || reader.EndOfStream) { if (buffer.Count > 0) { if (!reader.EndOfStream) { buffer.Add(c); yield return new String(buffer.ToArray()).Substring(0, buffer.Count - delimeter.Length); } else { buffer.Add(c); if (delim_buffer.ToString() != delimiter) yield return new String(buffer.ToArray()); else yield return new String(buffer.ToArray()).Substring(0, buffer.Count - delimeter.Length); } buffer.Clear(); } continue; } buffer.Add(c); } } private class CircularBuffer<T> : Queue<T> { private int _capacity; public CircularBuffer(int capacity) : base(capacity) { _capacity = capacity; } new public void Enqueue(T item) { if (base.Count == _capacity) { base.Dequeue(); } base.Enqueue(item); } public override string ToString() { List<String> items = new List<string>(); foreach (var x in this) { items.Add(x.ToString()); }; return String.Join("", items); } } }


Este fragmento de código leerá una línea de un archivo hasta que encuentre "/ n".

using (StreamReader sr = new StreamReader(path)) { string line = string.Empty; while (sr.Peek() >= 0) { char c = (char)sr.Read(); if (c == ''/n'') { //end of line encountered Console.WriteLine(line); //create new line line = string.Empty; } else { line += (char)sr.Read(); } } }

Como este código lee carácter por carácter, funcionará con un archivo de cualquier longitud sin estar limitado por la memoria disponible.


Implementaría algo así como la respuesta de George, pero como método de extensión que evita cargar todo el archivo a la vez (no probado, pero algo como esto):

static class ExtensionsForTextReader { public static IEnumerable<string> ReadLines (this TextReader reader, char delimiter) { List<char> chars = new List<char> (); while (reader.Peek() >= 0) { char c = (char)reader.Read (); if (c == delimiter) { yield return new String(chars.ToArray()); chars.Clear (); continue; } chars.Add(c); } } }

Que luego podría usarse como:

using (StreamReader sr = new StreamReader(FileName, Encoding.Default)) { foreach (var line in sr.ReadLines (''/n'')) Console.WriteLine (line); }


Me encantó la respuesta que dio @Pete. Me gustaría presentar una pequeña modificación. Esto le permitirá pasar un delimitador de cadena en lugar de un solo carácter:

using System; using System.IO; using System.Collections.Generic; internal static class StreamReaderExtensions { public static IEnumerable<string> ReadUntil(this StreamReader reader, string delimiter) { List<char> buffer = new List<char>(); CircularBuffer<char> delim_buffer = new CircularBuffer<char>(delimiter.Length); while (reader.Peek() >= 0) { char c = (char)reader.Read(); delim_buffer.Enqueue(c); if (delim_buffer.ToString() == delimiter || reader.EndOfStream) { if (buffer.Count > 0) { if (!reader.EndOfStream) { yield return new String(buffer.ToArray()).Replace(delimiter.Substring(0, delimiter.Length - 1), string.Empty); } else { buffer.Add(c); yield return new String(buffer.ToArray()); } buffer.Clear(); } continue; } buffer.Add(c); } } private class CircularBuffer<T> : Queue<T> { private int _capacity; public CircularBuffer(int capacity) : base(capacity) { _capacity = capacity; } new public void Enqueue(T item) { if (base.Count == _capacity) { base.Dequeue(); } base.Enqueue(item); } public override string ToString() { List<String> items = new List<string>(); foreach (var x in this) { items.Add(x.ToString()); }; return String.Join("", items); } } }


Necesitaba una solución que fuera hasta "/ r / n" y no se detuviera en "/ n". La solución de jp1980 funcionó, pero fue extremadamente lenta en un archivo grande. Entonces, convertí la solución de Mike Sackton para leer hasta encontrar una cadena especificada.

public static string ReadToString(StreamReader sr, string splitString) { char nextChar; StringBuilder line = new StringBuilder(); int matchIndex = 0; while (sr.Peek() > 0) { nextChar = (char)sr.Read(); line.Append(nextChar); if (nextChar == splitString[matchIndex]) { if(matchIndex == splitString.Length - 1) { return line.ToString().Substring(0, line.Length - splitString.Length); } matchIndex++; } else { matchIndex = 0; } } return line.Length == 0 ? null : line.ToString(); }

Y se llama así ...

using (StreamReader reader = new StreamReader(file)) { string line; while((line = ReadToString(reader, "/r/n")) != null) { Console.WriteLine(line); } }


O bien tiene que analizar la secuencia byte por byte usted mismo y manejar la división, o necesita usar el comportamiento ReadLine predeterminado que se divide en / r, / n, / / ​​r / n.

Si quieres analizar la transmisión byte a byte, usaría algo así como el siguiente método de extensión:

public static string ReadToChar(this StreamReader sr, char splitCharacter) { char nextChar; StringBuilder line = new StringBuilder(); while (sr.Peek() > 0) { nextChar = (char)sr.Read(); if (nextChar == splitCharacter) return line.ToString(); line.Append(nextChar); } return line.Length == 0 ? null : line.ToString(); }


Simplemente podría usar ReadToEnd () en el lector y luego usar String.Split para delimitarlo de cualquier forma que le parezca.



string text = sr.ReadToEnd(); string[] lines = text.Split(''/r''); foreach(string s in lines) { // Consume }