我想处理一个很长的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。我使用的解决方法解决了这个问题,但可能有更好的方法。
1条答案
按热度按时间vfhzx4xs1#
以“rb”模式打开文件。否则,Windows上的
read()
会将\r\n
转换为\n
,并接收比真实的文件大小更少的字节。