我有一个文本文件,我想逐行阅读并记录文本文件中的位置。在读取文件的任何一行后,程序可以退出,我需要在恢复时继续读取下一行的文件。
以下是一些示例代码:
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的倍数增加。现在我假设有一些缓冲正在进行,但我如何记录文件中的确切位置?
答案 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();