我正在努力解决二进制文件问题。我有以下课程:
class __attribute__((__packed__)) FileEntry {
unsigned char filename[8];
unsigned char extension[3];
unsigned char type;
unsigned char reserved;
unsigned char tenths_of_second;
unsigned short creation_time;
unsigned short creation_date;
unsigned short last_accessed;
unsigned short high_first_cluster;
unsigned short last_modification_time;
unsigned short last_modification_date;
unsigned short low_first_cluster;
unsigned int size;
};
我也有以下方法,就是给我这个问题的方法:
void Fat16FileSystem::writeToFS() {
BootSector b(512,128,1,1,2048,0,0xf8,128,32,64,2048,4194304);
FATTable f(b.total_sectors);
FileEntry fe;
char n = 0;
memset(&fe, 0, sizeof(fe));
//memset(&fi, 0, 512);
b.WriteToFS(file);
cout << "Writing the fillers" << endl;
for (int j = 0; j < (b.bytes_per_sector - 512)/512; j++) {
fwrite(&n, 1, 512, file);
}
cout << (b.bytes_per_sector - 512)/512 << " fillers was written" << endl;
f.writeToFs(file);
cout << "Writing " << b.directory_entries << " directory entries to FS" << endl;
for (int i = 0; i < b.directory_entries; i++) {
fwrite(&fe, sizeof(fe), 1, file);
}
fflush(file);
cout << "Writing " << b.large_total_sectors << " fillers to FS";
for (long k = 0; k < b.large_total_sectors; k++) {
fwrite(&n, 1, 512, file);
}
}
它似乎正在工作,直到它写入目录条目的部分,之后它似乎重写它的开始。使用十六进制编辑器我可以看到它写的字符与bootsector部分匹配。有人可以解释为什么吗?
答案 0 :(得分:1)
像fwrite(&n, 1, 512, file);
这样的构造容易出错。为避免错误,您应该从缓冲区推断项目的大小和项目数:
// ...
FILE* f = 0;
char n[512];
// ...
fwrite( n, sizeof n[0], sizeof n / sizeof n[0], f );
// ...
如果您更改n
的类型或其大小,您仍然会写出您期望的内容;这是缓冲区n
的内容(我不会用于缓冲区的名称)。
关于下面的评论,“不是fwrite(要写什么,要写什么,要写多少次,写什么地方?)”。你误解了第三个参数的含义。从MSDN: fwrite函数写入从缓冲区到输出流的每个大小长度的计数项。 换句话说,缓冲区的长度,以字节为单位,最多必须parameter2 * parameter3
。您的缓冲区是1个字节(char n
),但您写入512个字节。由于您要求fwrite
超出缓冲区的大小,这可能是垃圾的来源。
答案 1 :(得分:0)
for (int j = 0; j < (b.bytes_per_sector - 512)/512; j++) {
fwrite(&n, 1, 512, file);
}
此处未定义的行为。您正在从n
的地址开始读取512个字节,这只是一个字符。你最多只能阅读511字节的垃圾:在最坏的情况下,任何事情都可能发生,包括什么都没有。
您确定(b.bytes_per_sector - 512)/512
是否正确?看起来很奇怪。
您还忽略了fwrite()
的返回值。
for (int i = 0; i < b.directory_entries; i++) {
fwrite(&fe, sizeof(fe), 1, file);
}
这里的做法很差。您应该使用1作为第二个参数,使用字节计数作为第三个参数。否则,你不能被告知部分写入。这是fwrite()
和fread().
for (long k = 0; k < b.large_total_sectors; k++) {
fwrite(&n, 1, 512, file);
}
见上文从&n
重写512字节。
}