Fotis E.
Fotis E.

Reputation: 23

How to ensure that StreamReader.BaseStream.Length will return the correct value?

I have a loop which compares the BaseStream.Length with the lastMaxOffset and let's say that 9 out of 10 times runs properly.
But it's this 1 time that BaseStream.Length somehow sets equal to 0 - in debug mode it shows normal value, always greater than 0 - and this causes an issue to my console app. I verified that the length is NOT equal to 0 since it's a logfile which ONLY grows. So I guess this is a BaseStream issue (maybe temporarily hasn't the length value, so it sets it to 0) Is there a way to ensure that StreamReader.BaseStream.Length will return ONLY the correct value?

using (StreamReader reader = new StreamReader(
    new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), 
    Encoding.Default))
{
    long lastMaxOffset = this.getMaxOffsetForFile(path);
    if ( lastMaxOffset == 0 )
    {
        lastMaxOffset = this.setMaxOffsetForFile(path, reader.BaseStream.Length);
    }

    reader.DiscardBufferedData();
    long fileLength = reader.BaseStream.Length;

    if (fileLength > lastMaxOffset)
    { 
         //my code 
    }
}

Upvotes: 0

Views: 2978

Answers (1)

Hans Passant
Hans Passant

Reputation: 941317

You are reading a file that's actively being written to by another process. FileShare.ReadWrite gave you the backdoor to do this. That process has no obligation to make your life easy.

You are using FileStream.Length, there isn't anything wrong with it. It doesn't do anything but ask the operating system for the file size with GetFileSize(). You can always assume some kind of buggy network file system but that doesn't ever get you anywhere. The proper assumption to make here is that you actually see what this process does.

Once in a while it truncates the file. You'll get 0 when that happens. Or some other small number, it doesn't have to be 0 and it certainly doesn't have to repeat when you debug while the process continues to write to the file.

Nothing very unusual for log files, they can't grow forever. You'll have to write your code to accommodate for this. Very hard to do 100% correctly, you cannot depend on a reliable Length value. Only reasonable thing you can do when you get a new value that's less than the previous one is to assume the process started to rewrite the log file so you'll have to start reading again offset 0 (not Length and not lastMaxOffset). Using a telephone to talk to the programmer of this app to verify these assumptions is highly recommended.

Upvotes: 1

Related Questions