FileStream position is disabled after calling ReadLine () from C #

I am trying to read a file (small-ish) in chunks several lines at a time, and I need to go back to the beginning of certain chunks.

The problem is that after the very first call

streamReader.ReadLine();

The property is streamReader.BaseStream.Positionset to the end of the file! Now I assume that caching is done behind the scenes, but I expected this property to reflect the number of bytes that I used from this file. And yes, the file has more than one line :-)

For example, a call ReadLine()again (naturally) will return the next line in the file that does not start from the position previously reported streamReader.BaseStream.Position.

How can I find the actual position where the 1st line ends, so I can return there later?

I can only think of doing accounting manually by adding the line lengths returned by ReadLine (), but even here there are a few caveats:

  • ReadLine () decodes a new character (s), which can have a variable length (is is \ n)? Is it "\ r \ n"? Etc.)
  • I'm not sure if this will work fine with variable length characters.

... so now it seems like my only option is to rethink how I parse the file, so I don't need to rewind.

If this helps, I open my file as follows:

using (var reader = new StreamReader(
        new FileStream(
                       m_path, 
                       FileMode.Open, 
                       FileAccess.Read, 
                       FileShare.ReadWrite)))
{...}

Any suggestions?

+3
source share
4 answers

, , , ? .

- , : , ..

+4

, n- .

streamReader.BaseStream.Position , , .

, ReadLine(), . , , , , . .

. . , :

using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
    int ch;
    int currentLine = 1, offset = 0;

    while ((ch = fs.ReadByte()) >= 0)
    {
        offset++;

        // This covers all cases: \r\n and only \n (for UNIX files)
        if (ch == 10)
        {
            currentLine++;

            // ... do sth such as log current offset with line number
        }
    }
}

:

using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
    fs.Seek(yourOffset, SeekOrigin.Begin);
    TextReader tr = new StreamReader(fs);

    string line = tr.ReadLine();
}

, FileStream.

+4

StreamReader , , , , , FileStream.

+2

, ReadLine() , , - , , ReadLine(), , "" , . , ReadLine() , StreamReaders ReadLine(), , , OP.

, , StreamReaders, . Granger, : StreamReader , . : StreamReader, ( : -). , , StreamReader , - .

edit: I used the Granger solution and it works. Just make sure you enter this order: GetActualPosition (), then set BaseStream.Position to that position, then make sure you call DiscardBufferedData (), and finally you can call ReadLine () and you will get the full line, starting from the position specified in the method.

+1
source

Source: https://habr.com/ru/post/1747572/


All Articles