恐惧的怪异行为
Weird behaviour with fread
我正在从文件中读取二进制 uint32_t 数据,指示下一个二进制块的大小,之后我读取了该块,但读取指针 "moving" 错误。
FILE* file = fopen("file.zip", "r");
long pointerA = ftell(file);
uint32_t streamSize = 0;
fread(reinterpret_cast<char*>(&streamSize), sizeof streamSize,1,file);
long pointerB = ftell(file);
char* zipData = new char[streamSize];
fread(zipData, sizeof(char),streamSize,file);
long pointerC = ftell(file);
fseek( file, pointerA + 4 + streamSize, SEEK_SET );
long pointerD = ftell(file);
qDebug()<<"streamSize"<<streamSize<<"Positions"<<pointerA<<pointerB<<pointerC<<pointerD;
PointerA是原始位置,PointerB是读完那个uint32_t后的位置,PointerC是读完那个二进制数据后的指针,
PointerD 只是检查我认为应该是正确的行为。
现在让我们看看调试:
streamSize 2653 Positions 151 156 4627 2808
为什么流读取位置也移动了4627而不是2808?
提前感谢您的提示!
用户@alan-birtles 和@remy-lebeau 都是对的,我将其作为文本而不是二进制文件打开,这就是问题所在。
很遗憾,我无法将其标记为已解决。
PS。对于初学者,这意味着用 "rb" 而不是 "r" 打开文件。
您需要以二进制模式打开文件。当以文本模式打开文件时,某些字符会在您阅读时发生变化。例如在 Windows 上读取 '\n' 时返回“\r\n”。要以二进制模式打开,请将 'b' 添加到您的打开模式,例如:
FILE * file = fopen("file.txt", "rb");
请注意,您在编写二进制文件时需要执行相同的操作,否则会发生相同的转换。
std::fstream
也需要将 std::ios_base::binary
传递给 constructor/open 以避免同样的问题。
我正在从文件中读取二进制 uint32_t 数据,指示下一个二进制块的大小,之后我读取了该块,但读取指针 "moving" 错误。
FILE* file = fopen("file.zip", "r");
long pointerA = ftell(file);
uint32_t streamSize = 0;
fread(reinterpret_cast<char*>(&streamSize), sizeof streamSize,1,file);
long pointerB = ftell(file);
char* zipData = new char[streamSize];
fread(zipData, sizeof(char),streamSize,file);
long pointerC = ftell(file);
fseek( file, pointerA + 4 + streamSize, SEEK_SET );
long pointerD = ftell(file);
qDebug()<<"streamSize"<<streamSize<<"Positions"<<pointerA<<pointerB<<pointerC<<pointerD;
PointerA是原始位置,PointerB是读完那个uint32_t后的位置,PointerC是读完那个二进制数据后的指针, PointerD 只是检查我认为应该是正确的行为。
现在让我们看看调试:
streamSize 2653 Positions 151 156 4627 2808
为什么流读取位置也移动了4627而不是2808?
提前感谢您的提示!
用户@alan-birtles 和@remy-lebeau 都是对的,我将其作为文本而不是二进制文件打开,这就是问题所在。
很遗憾,我无法将其标记为已解决。
PS。对于初学者,这意味着用 "rb" 而不是 "r" 打开文件。
您需要以二进制模式打开文件。当以文本模式打开文件时,某些字符会在您阅读时发生变化。例如在 Windows 上读取 '\n' 时返回“\r\n”。要以二进制模式打开,请将 'b' 添加到您的打开模式,例如:
FILE * file = fopen("file.txt", "rb");
请注意,您在编写二进制文件时需要执行相同的操作,否则会发生相同的转换。
std::fstream
也需要将 std::ios_base::binary
传递给 constructor/open 以避免同样的问题。