使用fread()和fseek()在C中读取文件的一部分
我正在尝试将文件读入缓冲区,块大小为BLOCK_SIZE
(当前等于1000 unsigned chars
)。 我的代码最初找到了为了读取整个文件而必须读取的块数(通常为2-4),然后迭代通过for循环读取文件(忽略“ +17+filenamesize
”的东西,这就是全部在该计划的后期需要。
但是,仅在第一次,当j=1
,它是否实际将数据放入buf
数组中。 在其他情况下,当j != 1
, strlen(buf)
返回0 。
我认为问题是使用fseek()
在读取文件之前寻找文件的第二部分或者是内存分配问题。
任何帮助将被赞赏使它将文件的1000-1999
个字符读入buf
数组。
附件是代码的相关部分:
unsigned char *buf; source = fopen(localpath,"r"); temp = filesize / BLOCK_SIZE + 1; for (j=1; j <= temp; j++) { if (j == 1) { buf = (unsigned char *) malloc((sizeof(unsigned char)) * (BLOCK_SIZE + 17 + filenamesize)); fread(buf+17+filenamesize, sizeof(unsigned char), BLOCK_SIZE, source); } else if (j == temp) { buf = (unsigned char *) malloc((sizeof(unsigned char)) * (filesize + 5 - BLOCK_SIZE*(j-1))); fseek(source, BLOCK_SIZE*(j-1), SEEK_SET); // off by one warning fread(buf+5, sizeof(unsigned char), filesize - BLOCK_SIZE*(j-1), source); } else { buf = (unsigned char *) malloc((sizeof(unsigned char)) * (5+BLOCK_SIZE*(j-1))); fseek(source, BLOCK_SIZE*(j-1), SEEK_SET); // off by one warning fread(buf+5, sizeof(unsigned char), BLOCK_SIZE, source); } // do stuff with buf here buf = ""; free(buf); }
我建议检查fseek和fread的结果。 特别是,确保fseek返回0 – 如果不是,这可能是整个问题。
如果fseek成功,fread应该告诉你读取的总字节数。
另外,strlen不一定是有用的东西,因为它会假设这是一个以空字符结尾的字符串。 如果您读取的第一个字符是0字节,则strlen将返回0.您不会将此视为空终止字符串(您没有为空终止符分配足够的空间 – 正好适合您的二进制数据所需的空间) ,所以strlen可能不合适。
行buf = "";
对我来说看起来像个错误。 这会将指针buf设置为一个常量字符串,您也可以在下一行尝试free()
。 我会跳过这一行。
您似乎也会通过一些偏移读入缓冲区。 即在后两种情况下+5。 缓冲区的第一部分将是未定义的,请参见malloc
手册页。 所以strlen(buf)
对我来说感觉不明确。
srtlen返回字符串的长度(前0字节之前的字节数)。 如果buf [0]为0,则返回0.使用fread的返回值确定实际读取的字节数。
你也有内存泄漏。 您在每次循环迭代中都使用malloc,但最后只能释放一次。
你为什么要使用fseek? “首先检查文件有多大来确定读取块的次数”的概念从根本上是有缺陷的。 您应该只读取数据,直到没有剩余数据为止,例如:
while(BLOCK_SIZE ==(read_count = fread(buf,sizeof * buf,count,source)) do_stuff_with_buf(buf,read_count); if(ferror(source)) / *句柄错误* /;
(这个例子在短读时永远不会调用do_stuff_with_buf(),但这是一个微不足道的修改。)