我在virtualbox的windows xp上遇到了非常奇怪的问题。ReadFile()
函数拒绝在一次调用中读取超过16MB的数据。
它返回错误代码87(ERROR_INVALID_ARGUMENT
)。
看起来数据长度限制在24位。
这是一个示例代码,允许我找出确切的限制。
#include <conio.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <sys/stat.h>
int _tmain(int argc, _TCHAR* argv[])
{
int fd,len,readed;
char *buffer;
char *fname="Z:\\test.dat";
fd=_open(fname,_O_RDWR|_O_BINARY,_S_IREAD|_S_IWRITE);
if (fd==-1) {
printf("Error opening file : %s\n",strerror(errno));
getch();
return -1;
}
len=_lseek(fd,0,SEEK_END);
_lseek(fd,0,SEEK_SET);
if (!len) {
printf("File length is 0.\n");
getch();
return -2;
}
buffer=(char *)malloc(len);
if (!buffer) {
printf("Failed to allocate memory.\n");
getch();
return -3;
}
readed=0;
while (readed<len) {
len-=100;
readed=_read(fd,buffer,len);
if (len<=100) break;
}
if (readed!=len) {
printf("Failed to read file: result %d error %s\n",readed,strerror(errno));
getch();
return -4;
}
_close(fd);
printf("Success (%u).",len);
getch();
return 0;
}
文件长度为21MB。
结果是“
Z:\test.dat
”我试图在谷歌上找到同样的问题,但没有成功:(
可能有人知道问题的原因是什么?
最佳答案
问题不在于ReadFile()
本身。真正的问题是您的while()
循环从一开始就是错误的。您对len
和readed
变量的管理不正确。在循环的每次迭代中,您都会递减len
并重置readed
。最后,len
将递减为与readed
匹配的值,循环停止运行。您的“success”消息报告16MB是巧合,因为您在读取文件时同时修改了这两个变量。len
最初设置为21mb并倒计时,直到请求16mb时_read()
碰巧返回16mb缓冲区。这并不意味着ReadFile()
在16MB读取时失败(如果是这样,第一个循环迭代将失败,因为它要求21MB读取)。
你需要修正你的循环,而不是责备。正确的循环逻辑应该更像这样:
int total = 0;
while (total < len)
{
readed = _read(fd, &buffer[total], len-total);
if (readed < 1) break;
total += readed;
}
_close(fd);
if (total != len)
{
printf("Failed to read file: %d out of %d, error %s\n", total, len, strerror(errno));
...
return -4;
}
printf("Success (%u).",total);
...