IT TIP

Stream 개체에 대한 ReadAllLines?

itqueen 2021. 1. 5. 20:46
반응형

Stream 개체에 대한 ReadAllLines?


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

이 작업을 수행하는 방법이 있습니까? 아니면 파일을 한 줄씩 수동으로 반복해야합니까?


다음과 같이 한 줄씩 읽는 메서드를 작성할 수 있습니다.

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...


.EndOfStream속성은 대신 다음 줄 null가 아닌 경우 확인하는 루프에서 사용할 수 있습니다.

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

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

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. ReadLine does 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.

'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.

Thus for the input line1\r \r line3\r ReadLine returns 3 lines. The 2nd is empty. Split creates 4 strings. (There is an additional string after the last \r.) It then removes the 2nd and the 4th.

Note that Split is not well suited to parsing text lines which are "post-fix" delimited. That is the delimiter appears after the token. While Split is 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, Split returns 3 strings or 4 strings respectively.


If you want to use StreamReader then yes, you will have to use ReadLine and loop throught the StreamReader, reading line by line.

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

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

ReferenceURL : https://stackoverflow.com/questions/13312906/readalllines-for-a-stream-object

반응형