使用fread()和fseek()在C中读取文件的一部分

我正在尝试将文件读入缓冲区,块大小为BLOCK_SIZE (当前等于1000 unsigned chars )。 我的代码最初找到了为了读取整个文件而必须读取的块数(通常为2-4),然后迭代通过for循环读取文件(忽略“ +17+filenamesize ”的东西,这就是全部在该计划的后期需要。

但是,仅在第一次,当j=1 ,它是否实际将数据放入buf数组中。 在其他情况下,当j != 1strlen(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(),但这是一个微不足道的修改。)