FileStream.Seek() 和 SeekOrigin.Begin 是否针对不需要查找的情况进行了优化?
Does FileStream.Seek() with SeekOrigin.Begin optimize for when no seeking is necessary?
我有一个 class,它使用 FileStream
从大文件中一次读取一行图像数据。在内部,文件被分成块,每个块看起来像这样:
=================
| Header |
=================
| Data I Want |
=================
| Data I Ignore |
=================
要读取一行数据,我计算哪个块有我想要的行,Seek()
到适当的偏移量,并读取固定数量的字节。当从单个块中读取多行时,我实际上可以跳过所有 Seek()
调用,但第一个,因为在 Read()
之后指针已经在我想要的位置。但是我需要 Seek()
跳转到一个新块时。为简单起见,我总是计算文件中下一行的绝对偏移量,并使用 SeekOrigin.Begin
对其进行 Seek()
。 FileStream.Seek()
(或底层 SetFilePointer()
本机函数)是否经过优化以识别给定的搜索是空操作?如果没有,我可能应该优化我自己的代码,因为它不是快如闪电。
如果您查看此处的 FileStream.Seek 源代码:
http://referencesource.microsoft.com/#mscorlib/system/io/filestream.cs,329c77a859ac60bd
可以看到不管文件指针的旧位置如何,调用SeekCore方法,它自己调用了Win32Native.SetFilePointer,这是一个内核调用。
所以答案是否定的,没有优化,有能力的话还是自己优化吧。
答案似乎是肯定的。
这里唯一需要注意的是读取缓冲区。我们可以假设底层的 SetFilePointer() 调用将是一个 seek-to-current 的非操作。
当您查阅 source for Seek 时,您可以看到已尝试从读取缓冲区中保留尽可能多的内容。
我有一个 class,它使用 FileStream
从大文件中一次读取一行图像数据。在内部,文件被分成块,每个块看起来像这样:
================= | Header | ================= | Data I Want | ================= | Data I Ignore | =================
要读取一行数据,我计算哪个块有我想要的行,Seek()
到适当的偏移量,并读取固定数量的字节。当从单个块中读取多行时,我实际上可以跳过所有 Seek()
调用,但第一个,因为在 Read()
之后指针已经在我想要的位置。但是我需要 Seek()
跳转到一个新块时。为简单起见,我总是计算文件中下一行的绝对偏移量,并使用 SeekOrigin.Begin
对其进行 Seek()
。 FileStream.Seek()
(或底层 SetFilePointer()
本机函数)是否经过优化以识别给定的搜索是空操作?如果没有,我可能应该优化我自己的代码,因为它不是快如闪电。
如果您查看此处的 FileStream.Seek 源代码: http://referencesource.microsoft.com/#mscorlib/system/io/filestream.cs,329c77a859ac60bd
可以看到不管文件指针的旧位置如何,调用SeekCore方法,它自己调用了Win32Native.SetFilePointer,这是一个内核调用。
所以答案是否定的,没有优化,有能力的话还是自己优化吧。
答案似乎是肯定的。
这里唯一需要注意的是读取缓冲区。我们可以假设底层的 SetFilePointer() 调用将是一个 seek-to-current 的非操作。
当您查阅 source for Seek 时,您可以看到已尝试从读取缓冲区中保留尽可能多的内容。