2016-02-09 2 views
0

Я борюсь с бинарными файлами. У меня есть следующий класс:Получение мусора при попытке записи в двоичный файл

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); 

    } 

} 

Кажется, не будет работать до той части, где он пишет записи каталога, после чего, похоже, переписывает начало. Используя редактор Hex, я мог видеть, что символы, которые он пишут, совпадают с частью bootsector. Может кто-нибудь объяснить, почему?

+0

Не используйте литералы с fwrite: меньше головных болей. – ZDF

+0

@ZDF что вы имеете в виду? – FrankTominc

+0

@FrankTomnic См. Мой ответ ниже. – ZDF

ответ

0
for (int j = 0; j < (b.bytes_per_sector - 512)/512; j++) { 
    fwrite(&n, 1, 512, file); 
} 

Неопределенное поведение здесь. Вы читаете 512 байт, начиная с адреса n, который является только символом. В лучшем случае вы читаете 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); 
} 

См выше повторно писать 512 байт из &n.

}

+0

. Не 'fwrite (<что писать>, <размер того, что>, <сколько раз вы хотите написать это>, <где писать>) '? – FrankTominc

+0

Что касается '(b.bytes_per_sector - 512)/512' да, я думаю, что это правильно. Загрузочный сектор должен иметь 512 байт, если размер каждого сектора больше 512 байтов, он должен быть заполнен нулями. Он всегда будет кратным 512. – FrankTominc

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, чтобы выйти за пределы размера вашего буфера, это, вероятно, происхождение мусора.

Смежные вопросы