文件长度与C中的ftell()不一致

huwehgph  于 2023-10-16  发布在  其他
关注(0)|答案(1)|浏览(151)

我想处理一个很长的svg文件,但是我发现当阅读它到一个缓冲区,然后打印出缓冲区时,很多文本被写入缓冲区,超出了文件的结尾,我发现额外的文本已经从数据的结尾之前复制并添加。文件中的最后一段文本以svg标记结束,因此很容易看到结尾在哪里。对于常规文本文件,这将不太明显。当尝试使用图像应用程序或浏览器打开此类文件时,应用程序会因为此尾随文本而感到困惑。
最后我发现由于某种原因,函数ftell()返回的文件长度太大。下面是我的函数的简化版本:

int datReadFileToBuf(char* fn, BYTE** buf) {
  int fileLen = 0;

  if (*buf != NULL) return -1;  // ERROR: The buffer should be NULL.
  FILE* fp = NULL;
  if (fopen_s(&fp, fn, "r") != 0) return -2;
  fseek(fp, 0, SEEK_END);
  fileLen = ftell(fp);
  rewind(fp);
  if ((*buf = (BYTE*)calloc(fileLen, 1)) == NULL) return -3;
  size_t sizetLen = fread(*buf, 1, fileLen, fp);
  // fileLen  == 483553
  // sizetLen == 481976
  fclose(fp);
  // return fileLen; // Bad
  return sizetlen;   // Good
}

负返回值表示错误,fn是文件名,buf是缓冲区,在main()函数中声明为BYTE* datInBuf = NULL,并与fn一起传递给datReadFileToBuf()。通过返回sizeLen作为缓冲区的长度,程序的其余部分可以正常工作,因为缓冲区的其余部分被忽略,但是返回fileLen会导致问题,因为它更大。
这似乎是长文本文件的问题。我没有检查过这种情况是否发生在二进制文件中。我已经在网上搜索了ftell()的问题,但是没有找到任何解释,所以如果能提供一些关于这个问题的信息,我将非常感激。顺便说一句,我在Windows 10平台上使用Visual Studio 2022。我使用的解决方法解决了这个问题,但可能有更好的方法。

vfhzx4xs

vfhzx4xs1#

以“rb”模式打开文件。否则,Windows上的read()会将\r\n转换为\n,并接收比真实的文件大小更少的字节。

相关问题