C# Stream 对象的 ReadAllLines?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13312906/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ReadAllLines for a Stream object?
提问by Ryan Peschel
There exists a File.ReadAllLinesbut not a Stream.ReadAllLines.
存在 aFile.ReadAllLines但不存在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();
}
Does there exist a way to do this or do I have to manually loop through the file line by line?
有没有办法做到这一点,还是我必须逐行手动循环遍历文件?
采纳答案by Jon Skeet
You can write a method which reads line by line, like this:
您可以编写一个逐行读取的方法,如下所示:
public IEnumerable<string> ReadLines(Func<Stream> streamProvider,
Encoding encoding)
{
using (var stream = streamProvider())
using (var reader = new StreamReader(stream, encoding))
{
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
Then call it as:
然后将其称为:
var lines = ReadLines(() => Assembly.GetExecutingAssembly()
.GetManifestResourceStream(resourceName),
Encoding.UTF8)
.ToList();
The Func<>part is to cope when reading more than once, and to avoid leaving streams open unnecessarily. You could easily wrap that code up in a method, of course.
这Func<>部分是为了应对多次阅读,并避免不必要地打开流。当然,您可以轻松地将该代码封装在一个方法中。
If you don't need it all in memory at once, you don't even need the ToList...
如果您一次不需要将其全部存储在内存中,那么您甚至不需要ToList...
回答by Steve Danner
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);
}
回答by Coding Duchess
If you want to use StreamReader then yes, you will have to use ReadLine and loop throught the StreamReader, reading line by line.
如果您想使用 StreamReader 那么是的,您将必须使用 ReadLine 并循环遍历 StreamReader,逐行读取。
Something like that:
类似的东西:
string line;
using (StreamReader reader = new StreamReader(stream))
{
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
or try
或尝试
using (StreamReader reader = new StreamReader("file.txt"))
{
string[] content = reader.ReadToEnd().Replace("\n","").Split('\t');
}
回答by Bryan Johnson
The .EndOfStreamproperty can be used in the loop instead of checking if the next line is not null.
该.EndOfStream属性可以在循环中使用,而不是检查下一行是否为空。
List<string> lines = new List<string>();
using (StreamReader reader = new StreamReader("example.txt"))
{
while(!reader.EndOfStream)
{
lines.Add(reader.ReadLine());
}
}
回答by Andrew Dennison
The use of Splithere:
Split这里的使用:
reader
.ReadToEnd()
.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
is not equivalent to ReadLine. If you look at the source for ReadLine, StreamReader.cs, you will see that it handles line terminators: \r, \n, and \r\n correctly. ReadLinedoes not return an extra empty string when the line terminator is \r\n, which is typical in DOS/Windows. Split"sees" (parses) \r followed by \n as 2 separate delimiters and returns an empty string.
不等于ReadLine。如果你看一下源ReadLine,StreamReader.cs,你会看到,它处理行结束符:\ r \ n和\ r \ n正确。ReadLine当行终止符为 \r\n 时,不会返回额外的空字符串,这在 DOS/Windows 中很常见。Split“看到”(解析) \r 后跟 \n 作为 2 个单独的分隔符并返回一个空字符串。
'StringSplitOptions.RemoveEmptyEntries' in the above code does remove these empty strings, but it will also remove any empty lines which appear in the input as well.
上面代码中的 'StringSplitOptions.RemoveEmptyEntries' 确实删除了这些空字符串,但它也会删除出现在输入中的任何空行。
Thus for the input
line1\r
\r
line3\r
ReadLinereturns 3 lines. The 2nd is empty.
Splitcreates 4 strings. (There is an additional string after the last \r.) It then removes the 2nd and the 4th.
因此对于输入 line1\r \r line3\r
ReadLine返回 3 行。第二个是空的。
Split创建 4 个字符串。(在最后一个 \r 之后有一个额外的字符串。)然后删除第二个和第四个。
Note that Splitis not well suited to parsing text lines which are "post-fix" delimited. That is the delimiter appears after the token. While Splitis suitable for infix, where the delimiters appear between the tokens. It is the difference between a,b,c and line1\r,line2,line3\r. For these inputs, Splitreturns 3 strings or 4 strings respectively.
请注意,Split它不太适合解析以“后修复”分隔的文本行。即分隔符出现在令牌之后。WhileSplit适用于中缀,其中分隔符出现在标记之间。它是 a,b,c 和 line1\r,line2,line3\r 之间的区别。对于这些输入,分别Split返回 3 个字符串或 4 个字符串。
回答by Fidel
Using the following extension method:
使用以下扩展方法:
public static class Extensions
{
public static IEnumerable<string> ReadAllLines(this StreamReader reader)
{
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
It's possible to get to your desired code:
可以得到你想要的代码:
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Test_Resources.Resources.Accounts.txt"))
using (StreamReader reader = new StreamReader(stream))
{
string[] result = reader.ReadAllLines().ToArray();
}

