如何确保StreamReader.BaseStream.Length将返回正确的值?

时间:2015-10-20 09:39:28

标签: c# streamreader content-length

我有一个循环,将BaseStream.LengthlastMaxOffset进行比较,让我们说10次中有9次正常运行。
但是这一次BaseStream.Length以某种方式设置为0 - 在调试模式下它显示正常值,总是大于0 - 这会导致我的控制台应用程序出现问题。 我验证了长度不等于0,因为它只是一个只增长的日志文件。所以我猜这是一个BaseStream问题(可能暂时没有长度值,所以它将它设置为0) 有没有办法确保StreamReader.BaseStream.Length只返回正确的值?

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

1 个答案:

答案 0 :(得分:1)

您正在阅读另一个进程正在写入的文件。 FileShare.ReadWrite为您提供了后门。这个过程没有义务让你的生活变得轻松。

您正在使用FileStream.Length,它没有任何问题。除了使用GetFileSize()向操作系统询问文件大小外,它什么也没做。您总是可以假设某种有缺陷的网络文件系统,但这并不能让您随处可见。这里做出的正确假设是你实际上看看这个过程的作用。

偶尔它会截断文件。当发生这种情况时你会得到0。或者其他一些小数字,它不必为0,当进程继续写入文件时,调试时肯定不需要重复。

日志文件没有什么不寻常之处,它们无法永远增长。您必须编写代码以适应此目的。很难做到100%正确,你不能依赖可靠的长度值。当你得到一个小于前一个值的新值时,你可以做的唯一合理的事情是假设进程开始重写日志文件,所以你必须再次开始读取偏移0(不是Length而不是lastMaxOffset)。强烈建议使用电话与该应用程序的程序员交谈以验证这些假设。