我正在研究一种文件格式,应该在几种不同的操作系统和计算机上编写和读取.其中一些计算机应该是x86计算机,其他计算机应该是x86-64.其他一些处理器可能存在,但我不关心他们还没有.
此文件格式应包含几个可读取的数字,如下所示:
struct LongAsChars{
char c1, c2, c3, c4;
};
long readLong(FILE* file){
int b1 = fgetc(file);
int b2 = fgetc(file);
int b3 = fgetc(file);
int b4 = fgetc(file);
if(b1<0||b2<0||b3<0||b4<0){
//throwError
}
LongAsChars lng;
lng.c1 = (char) b1;
lng.c2 = (char) b2;
lng.c3 = (char) b3;
lng.c4 = (char) b4;
long* value = (long*) &lng;
return *value;
}
Run Code Online (Sandbox Code Playgroud)
写作:
void writeLong(long x, FILE* f){
long* xptr = &x;
LongAsChars* lng = (LongAsChars*) xptr;
fputc(lng->c1, f);
fputc(lng->c2, f);
fputc(lng->c3, f);
fputc(lng->c4, f);
}
Run Code Online (Sandbox Code Playgroud)
虽然这似乎在我的计算机上工作,但我担心它可能不在其他人或文件格式可能最终在计算机之间变得不同(例如32位与64位计算机).难道我做错了什么?我应该如何实现我的代码以使用每个数字的常量字节数?
我应该只使用fread(这可能会使我的代码更快)吗?
使用类型stdint.h确保您输入和输出相同的字节数.
然后你只是处理字节序问题,你可能没有真正处理它.
使用别名char*序列化long会在写入的文件中为不同的字节顺序留下不同的字节顺序.
你应该像这样分解字节:
char c1 = (val >> 0) & 0xff;
char c2 = (val >> 8) & 0xff;
char c3 = (val >> 16) & 0xff;
char c4 = (val >> 24) & 0xff;
Run Code Online (Sandbox Code Playgroud)
然后使用类似的东西重新组合:
val = (c4 << 24) |
(c3 << 16) |
(c2 << 8) |
(c1 << 0);
Run Code Online (Sandbox Code Playgroud)