我正在使用带有CreateFile()
和FILE_FLAG_NO_BUFFERING
标记的FILE_FLAG_WRITE_THROUGH
打开文件有几个原因,我注意到了一个奇怪的行为:
由于使用这些标志我们必须分配与扇区大小对齐的内存,假设扇区大小为512.
现在,如果我用_aligned_malloc()
分配512个字节并且我从文件中读取,如果文件大小恰好是扇区大小的倍数,那么一切正常,比如512 * 4或2048.我读了512个字节的片段和最后一个片段使ReadFile()
返回EOF代码,即返回FALSE
和GetLastError()
设置为ERROR_HANDLE_EOF
。
当文件大小与扇区大小不对齐时,问题就出现了,也就是说,文件的大小是2048 + 13或2061字节。
我可以从文件中成功读取前4个512大小的块,并且对ReadFile()
的第5个调用让我从文件中读取最新的13个剩余字节,但这是奇怪的事情:在这样的案例ReadFile()
不会返回EOF代码!即使我告诉ReadFile()
读取512个字节,并且它只读取13个字节(因此它超过了文件末尾),它也没有告诉我,并且只返回13个字节读取,而没有其他进一步的信息。
因此,当我读取最后13个字节并且我的循环设置为读取直到EOF时,它将再次调用ReadFile()
第6次,导致错误:ERROR_INVALID_PARAMETER
我猜这是是的,因为我在超过文件结尾后试图阅读!
我的问题是:这是正常行为还是我做错了什么?当使用非缓冲I / O时,我应该在读取最后一个非扇区对齐的文件块时没有EOF代码?或者有另一种方法可以做到这一点? 我怎么能理解我刚刚通过了EOF? 我想我可以通过修改循环来解决这个问题:直到EOF,我才能读取直到EOF OR ,直到实际返回的字节小于读取的请求字节。这是正确的假设吗?
注意:使用带有普通标志的文件时,不会发生,只有在我使用FILE_FLAG_NO_BUFFERING
和FILE_FLAG_WRITE_THROUGH
时才会发生。
注2:我正在使用I / O完成端口来读取文件,但我想这也是在不使用它们的情况下发生的,只需使用阻塞I / O.
答案 0 :(得分:3)
feof
功能也经常被误解。
基本上,你在第一种情况下得到ERROR_HANDLE_EOF
来区分“512字节读取,更多读取”和“512字节读取,没有剩下”的情况。
在秒的情况下,这不是必需的。 “请求512个字节,读取13个字节,没有错误”已经意味着您已经处于EOF状态。部分阅读的任何其他原因都是错误的。