为什么FileStream.Position以1024的倍数递增?

时间:2010-09-23 16:53:21

标签: c# file file-io

我有一个文本文件,我想逐行阅读并记录文本文件中的位置。在读取文件的任何一行后,程序可以退出,我需要在恢复时继续读取下一行的文件。

以下是一些示例代码:

using (FileStream fileStream = new FileStream("Sample.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    fileStream.Seek(GetLastPositionInFile(), SeekOrigin.Begin);
    using (StreamReader streamReader = new StreamReader(fileStream))
    {
        while (!streamReader.EndOfStream)
        {
            string line = streamReader.ReadLine();
            DoSomethingInteresting(line);
            SaveLastPositionInFile(fileStream.Position);

            if (CheckSomeCondition())
            {
                break;
            }
        }
    }
}

当我运行此代码时,fileStream.Position的值在读取每一行后不会改变,它只会在读取几行后前进。当它发生变化时,它会以1024的倍数增加。现在我假设有一些缓冲正在进行,但我如何记录文件中的确切位置?

3 个答案:

答案 0 :(得分:10)

这不是FileStream负责的 - 它是StreamReader。为了提高效率,它一次读取1K。

StreamReader方面跟踪流的有效位置是棘手的...特别是ReadLine将丢弃该行结尾,所以你无法准确地重建原始数据(它可能以“\ n”或“\ r \ n”结束)。如果StreamReader暴露了一些东西以使其变得更容易(我很确定可以这样做而没有太多困难)会很好,但我不认为当前的API中有任何东西帮助你:(

顺便说一下,我建议您不要使用EndOfStream,而是继续阅读,直到ReadLine返回null。这让我感觉更简单:

string line;
while ((line = reader.ReadLine()) != null)
{
    // Process the line
}

答案 1 :(得分:2)

我同意Stefan M.,这可能是导致职位不正确的缓冲。如果它只是你想要跟踪的字符数,那么我建议你自己动手,如:

        using(FileStream fileStream = new FileStream("Sample.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
            fileStream.Seek(GetLastPositionInFile(), SeekOrigin.Begin);
            **Int32 position = 0;**
            using(StreamReader streamReader = new StreamReader(fileStream)) {
                while(!streamReader.EndOfStream) {
                    string line = streamReader.ReadLine();
                    **position += line.Length;**
                    DoSomethingInteresting(line);
                    **SaveLastPositionInFile(position);**

                    if(CheckSomeCondition()) {
                        break;
                    }
                }
            }
        }

答案 2 :(得分:0)

假设您的文件不是太大,为什么不在大块中读取整个内容然后操纵字符串 - 可能比停止更快并且去i / o。

例如,

            //load entire file
            StreamReader srFile = new StreamReader(strFileName);
            StringBuilder sbFileContents = new StringBuilder();
            char[] acBuffer = new char[32768];
            while (srFile.ReadBlock(acBuffer, 0, acBuffer.Length)
                > 0)
            {
                sbFileContents.Append(acBuffer);
                acBuffer = new char[32768];
            }

            srFile.Close();