2016-09-30 7 views
5

Я написал программу, которая сжимает два небольших файла в файл с одним большим файлом. Сначала я читал данные из входных файлов, объединяя данные и записывал вывод в временный файл. После этого я переименую файл temp в нужное имя файла (находящееся в том же разделе на диске). Вот псевдокод:Проверьте, действительно ли содержимое файла записано на диск - не поставлено в буфер буфера контроллера

FILE* fp_1 = fopen("file_1.dat", "r+b"); 
FILE* fp_2 = fopen("file_2.dat", "r+b"); 
FILE* fp_out = fopen("file_tmp.dat", "w+b"); 

// 1. Read data for the key in two files 
const char* data_1 = ...; 
const char* data_2 = ...; 

// 2. Merge data, store in an allocated buffer 

// 3. Write merged buffer to temp file 
fwrite(temp_buff, estimated_size, 1, fp_out); 
fflush(fp_out); 

fclose(fp_1); 
fclose(fp_2); 
fclose(fp_out); 

// Now rename temp file to desired file name 
if(std::rename("file_tmp.dat", "file_out.dat") == 0) 
{ 
    std::remove("file_1.dat"); 
    std::remove("file_2.dat"); 
} 

Я неоднократно тестировал программу с двумя входными файлами 5 МБ каждый. Однажды я внезапно выключил систему, отключив кабель питания. После перезапуска системы я проверил данные и обнаружил, что входные файлы были удалены, и file_out.dat был заполнен всеми нулями. Это заставило меня поверить, что система спустилась сразу после удаления 2 входных файлов, а выходные данные все еще находились где-то в буфере контроллера диска. Если это так, то есть ли способ проверить, действительно ли данные записаны на диск?

+1

Увидев, что ОС даже не знает наверняка (у диска, скорее всего, есть собственный кеш RAM), это сложная проблема. – user4581301

ответ

5

Не в общем случае. Диск может лежать в ОС, заявляя, что запись закончена, когда она действительно просто поставлена ​​в очередь в кеш-память RAM на жестком диске, которая будет потеряна при резких потерях мощности.

Лучшее, что вы можете сделать, это явно попросить ОС рассказать диск, чтобы «на самом деле, на самом деле синхронизировать все» после того, как вы выполнили fflush, либо ограниченные возможности с fsync или использовать что-то вроде sync or syncfs (бывших синхронизирует все файловые систем, последний ограничивает область действия файловой системой, соответствующей одному файловому дескриптору). Вы хотите сделать целевую fsync после окончательного fflush но до rename, и/или более широкий sync/syncfs после rename но до remove вызовов, так что данные и файлы, системные таблицы, безусловно, обновляются, прежде чем удалить исходные файлы ,

Конечно, как я уже сказал, это все самое лучшее усилие; если контроллер диска лежит на ОС, вы ничего не можете сделать, чтобы писать новые прошивки и драйверы для диска, что, вероятно, заходит слишком далеко.

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

  • Нет связанных вопросов^_^