ReadAllLines para un objeto Stream?

Existe un File.ReadAllLines pero no un Stream.ReadAllLines .

 using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Test_Resources.Resources.Accounts.txt")) using (StreamReader reader = new StreamReader(stream)) { // Would prefer string[] result = reader.ReadAllLines(); string result = reader.ReadToEnd(); } 

¿Existe una forma de hacerlo o tengo que pasar manualmente el archivo línea por línea?

Puede escribir un método que lea línea por línea, así:

 public IEnumerable ReadLines(Func streamProvider, Encoding encoding) { using (var stream = streamProvider()) using (var reader = new StreamReader(stream, encoding)) { string line; while ((line = reader.ReadLine()) != null) { yield return line; } } } 

Luego llámalo como:

 var lines = ReadLines(() => Assembly.GetExecutingAssembly() .GetManifestResourceStream(resourceName), Encoding.UTF8) .ToList(); 

La parte Func<> es para hacer frente a la lectura más de una vez, y para evitar dejar las secuencias abiertas innecesariamente. Podría envolver fácilmente ese código en un método, por supuesto.

Si no lo necesita todo en la memoria a la vez, ni siquiera necesita ToList

La propiedad .EndOfStream se puede usar en el bucle en lugar de verificar si la siguiente línea no es nula.

 List lines = new List(); using (StreamReader reader = new StreamReader("example.txt")) { while(!reader.EndOfStream) { lines.Add(reader.ReadLine()); } } 
 using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Test_Resources.Resources.Accounts.txt")) using (StreamReader reader = new StreamReader(stream)) { // Would prefer string[] result = reader.ReadAllLines(); string[] result = reader.ReadToEnd().Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); } 

El uso de Split aquí:

 reader .ReadToEnd() .Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); 

no es equivalente a ReadLine . Si mira la fuente de ReadLine , StreamReader.cs , verá que maneja los terminadores de línea: \ r, \ n, y \ r \ n correctamente. ReadLine no devuelve una cadena vacía adicional cuando el terminador de línea es \ r \ n, que es típico en DOS / Windows. Split “ve” (analiza) \ r seguido de \ n como 2 separadores separados y devuelve una cadena vacía.

‘StringSplitOptions.RemoveEmptyEntries’ en el código anterior elimina estas cadenas vacías, pero también eliminará cualquier línea vacía que aparezca en la entrada.

Por lo tanto, para la línea de entrada1 \ r \ ReadLine \ r ReadLine devuelve 3 líneas. El 2do está vacío. Split crea 4 cadenas. (Hay una cadena adicional después de la última \ r.) Luego elimina la 2da y la 4ta.

Tenga en cuenta que Split no es muy adecuado para analizar líneas de texto que están delimitadas “después de la corrección”. Ese es el delimitador que aparece después del token. Mientras que Split es adecuado para infijo, donde los delimitadores aparecen entre los tokens. Es la diferencia entre a, b, c y line1 \ r, line2, line3 \ r. Para estas entradas, Split devuelve 3 cadenas o 4 cadenas, respectivamente.

Si desea usar StreamReader, entonces sí, deberá usar ReadLine y recorrer el StreamReader, leyendo línea por línea.

Algo como eso:

 string line; using (StreamReader reader = new StreamReader(stream)) { while ((line = reader.ReadLine()) != null) { Console.WriteLine(line); } } 

o tratar

 using (StreamReader reader = new StreamReader("file.txt")) { string[] content = reader.ReadToEnd().Replace("\n","").Split('\t'); }