3

I have a text file and I want to read this text file from a particular till end of file.

I can do this by the following way.

string path = @"C:\abc.txt";
var pp = File.ReadAllLines(path).Skip(1).Take(2);

But I want this to be done using StreamReader only.

I'm doing this, but its not giving proper result.

using (Stream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
        using (StreamReader streamReader = new StreamReader(stream))
        {
                var str = streamReader.ReadLine().Skip(1).Take(2);
        }
}

I can do this by the following way too. but I want to avoid the for loop.

using (Stream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    using (StreamReader streamReader = new StreamReader(stream))
    {
                int count=2;
                for (int i = 0; i < count; i++)
                {
                    streamReader.ReadLine();
                }
                string data = streamReader.ReadLine();
    }
}

My question is not duplicate at all, previous one is about reading all files but my question is read from specific line till end.

Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
  • 2
    Possible duplicate of [ReadAllLines for a Stream object?](http://stackoverflow.com/questions/13312906/readalllines-for-a-stream-object) – Quentin Roger Oct 04 '16 at 12:01

1 Answers1

1

You want just two lines - Skip(1).Take(2) - why don't read them directly?

  using (StreamReader streamReader = new StreamReader(stream)) {
    streamReader.ReadLine(); // skip the first line

    // take next two lines
    string[] data = new string[] {
      streamReader.ReadLine(),
      streamReader.ReadLine(),
    }; 

    ...
  }

Please, notice that you current code with StreamReader equals to Skip(2).Take(1).First(). In general case - Skip(M).Take(N) -, you have to use for loops (or their emulation):

   using (StreamReader streamReader = new StreamReader(stream)) {
     // Skip M first items
     for (int i = 0; i < M; ++i)
       streamReader.ReadLine();

     string[] data = new string[N];

     // Take N next items 
     for (int i = 0; i < N; ++i)
       data[i] = streamReader.ReadLine(); 
   }
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • skip(m).Take(n)...m and n can be any integer, so I cant do this way – Vivek Nuna Oct 04 '16 at 12:18
  • but I want to do this without loop, as it can be done by File.ReadAllLines() method. so drawback of this solution is reading first m lines is waste of memory, if I want to read after m lines – Vivek Nuna Oct 04 '16 at 12:23
  • @vivek nuna:`File.ReadAllLines()` returns all the lines (btw. `File.ReadLines()` is more efficient in the context) by using *loops* (`while`), and `Take(N)` is *loop* based as well. See for reference https://referencesource.microsoft.com/#mscorlib/system/io/file.cs,675b2259e8706c26 and https://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,aae92b018fa12b39. So you can *hide* loops, but not *eliminate* them – Dmitry Bychenko Oct 04 '16 at 12:27