尝试写入二进制文件

时间:2016-02-09 04:35:00

标签: c++ binaryfiles fwrite garbage

我正在努力解决二进制文件问题。我有以下课程:

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部分匹配。有人可以解释为什么吗?

2 个答案:

答案 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字节。

}