Stream对象的ReadAllLines?

时间:2012-11-09 17:23:23

标签: c# file text stream

存在File.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();
}

是否有办法执行此操作或是否必须逐行手动循环遍历文件?

6 个答案:

答案 0 :(得分:96)

您可以编写一个逐行读取的方法,如下所示:

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;
        }
    }
}

然后将其称为:

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

Func<>部分是在不止一次阅读时应对,并避免不必要地打开流。当然,您可以轻松地将该代码包装在一个方法中。

如果你不需要一次在内存中,你甚至不需要ToList ......

答案 1 :(得分:35)

可以在循环中使用.EndOfStream属性,而不是检查下一行是否为空。

List<string> lines = new List<string>();

using (StreamReader reader = new StreamReader("example.txt"))
{
    while(!reader.EndOfStream)
    {
        lines.Add(reader.ReadLine());
    }
}

答案 2 :(得分:6)

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);
}

答案 3 :(得分:6)

在这里使用Split

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

不等同于ReadLine。如果查看ReadLineStreamReader.cs的来源,您会看到它正确处理行终止符:\ r,\ n和\ r \ n。当行终止符为\ r \ n时,ReadLine不返回额外的空字符串,这在DOS / Windows中是典型的。 Split&#34;看到&#34; (解析)\ r后跟\ n作为2个单独的分隔符并返回一个空字符串。

&#39; StringSplitOptions.RemoveEmptyEntries&#39;在上面的代码中确实删除了这些空字符串,但它也将删除输入中出现的任何空行。

因此对于输入     第1行\ r     \ r     3号线\ r ReadLine返回3行。第二个是空的。 Split创建4个字符串。 (在最后一个\ r \ n后面还有一个字符串。)然后删除第二个和第四个。

请注意,Split不适合解析“修复后”的文本行。分隔。这是在令牌之后出现的分隔符。虽然Split适合于中缀,但分隔符出现在令牌之间。它是a,b,c和line1 \ r \ n,line2,line3 \ r \ n之间的差异。对于这些输入,Split分别返回3个字符串或4个字符串。

答案 4 :(得分:0)

如果你想使用StreamReader,那么你必须使用ReadLine并循环读取StreamReader,逐行阅读。

类似的东西:

string line;

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

或尝试

using (StreamReader reader = new StreamReader("file.txt"))
    {

       string[] content = reader.ReadToEnd().Replace("\n","").Split('\t');
    }

答案 5 :(得分:0)

使用以下扩展方法:

public static class Extensions
{
    public static IEnumerable<string> ReadAllLines(this StreamReader reader)
    {
        string line;
        while ((line = reader.ReadLine()) != null)
        {
            yield return line;
        }
    }
}

可以获取所需的代码:

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