Форум: "WinAPI";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];
ВнизTerminateProcess Найти похожие ветки
← →
Суслик © (2005-04-26 16:51) [80]
> Если не в сети, то должно может будет достататочно FlushFileBuffers,
> как советовал mgcr ?
Да я тоже так думаю, что достаточно.
Т.е. ты тоже думаешь, что достаточно?
← →
mgcr © (2005-04-26 17:01) [81]Суслик © (26.04.05 16:23) [78]
> Сохранение раз в 10 минут файла до 3 мб таким образом, чтобы
> при аппаратных сбоях (выключение компьютера) при последующем
> восстановлении либо было понятно, что произошел сбой (т.е.
> новый файл не дописался), либо новый файл дописался и информации
> о сбое нет. В первом случае происходит восстановление старого
> файла
Вообще-то это делает любой редактор, создавая резервную копию. Word, например, создает специальный файл, маленький, в том числе и для этих целей.
← →
Sha © (2005-04-26 17:20) [82]> Суслик © (26.04.05 16:51) [80]
Можно проверить
procedure TSenderForm.Button1Click(Sender: TObject);
var
fi: file;
begin
AssignFile(fi,"aaa"); Rewrite(fi,1);
BlockWrite(fi,"bbb",3);
//FlushFileBuffers(TFileRec(fi).Handle);
ShowMessage("ccc");
CloseFile(fi);
end;
Пускаем как есть, OK не говорим.
Под 98 размер файла должен быть 0.
Говорим OK - размер меняется на 3.
Значит метаданные в оглавлении обновляются по Close.
Повторяем с раскомментированным FlushFileBuffers.
Видим, что метаданные обновлены до Close.
Все как ты хотел.
← →
alpet © (2005-04-26 17:22) [83]Маленький итог:
1. Необходимо - сбрасывать данные на жесткий диск принудительно.
Самое простое для этого использовать функцию FFB (FlushFileBuffers).
2. После завершения этой операции создавать дополнительный файл как доказательство что первый уже записался.
3. Дополнительно: Как защиту от непредвиденных ситуаций можно создавать копию первого файла.
Что еще не хватает для решения задачи?
← →
Sha © (2005-04-26 17:31) [84]Тут важный момент: Close сам не обновляет даннае в оглавлении, а лишь просит ОС сделать это.
Отсюда выводы:
- Выполнение Close не гарантирует обновление метаданных при отключении питания,
- То, что отложеный вызов FlushFileBuffers делает ОС увеличивает быстродействие приложения,
- Самостоятельно вызывая FlushFileBuffers ты обновляешь данные в оглавлении, но проигрываешь в скорости.
← →
mgcr © (2005-04-26 17:35) [85]Sha © (26.04.05 13:35) [59]
<offtopic>
> > Это я к тому, что цепочечную файловую систему трудно сделать
> надежной
>
> Делал, и даже на ЕС.
Был во время оно на ЕС такой продукт Librarian (отечественный вариант носил название "Ритм") со всякими Jobstream-файлами и аккурат цепочечной организацией внутренних файлов данных, в отличие от экстентной.
Не знакомо ?
</offtopic>
← →
Sha © (2005-04-26 17:38) [86]> alpet © (26.04.05 17:22) [83]
Вроде п.п. 2 и 3 лишние
← →
Sha © (2005-04-26 17:41) [87]> mgcr © (26.04.05 17:35) [85]
> Был во время оно на ЕС такой продукт Librarian...
> Не знакомо ?
Неа, у меня был свой...
← →
Суслик © (2005-04-26 17:42) [88]
> [86] Sha © (26.04.05 17:38)
> > alpet © (26.04.05 17:22) [83]
> Вроде п.п. 2 и 3 лишние
как раз вопрос о транзакционности flushfilebuffer. Может быть пока идет скидывание комп упадет и не скинется до конца - половина новая, половина старая. Где гарантия, что этого не будет?
← →
alpet © (2005-04-26 17:44) [89]Sha © (26.04.05 17:38) [86]
2. Как иначе доказать что файл был записан полностью, а не частично?
3. Это только метод перестраховки (вирусы, проблемы с жестким диском).
← →
alpet © (2005-04-26 17:47) [90]Суслик © (26.04.05 17:42) [88]
Пока FFB скидывает содержимое буферов на диск - управление не вернется. Если после ее отработки закрыть описатель файла, и создать второй (копию 1:1) и обойтись с ним так же, о наличии сбоя можно будет судить по отсутствию второго файла (до него просто дело не дойдет) либо по наличию отличий между вторым и первым файлом.
← →
mgcr © (2005-04-26 17:53) [91]
> Может быть пока идет скидывание комп упадет и не скинется
> до конца - половина новая, половина старая. Где гарантия,
> что этого не будет?
В End-Of-File pointer
← →
Суслик © (2005-04-26 17:57) [92]
> [91] mgcr © (26.04.05 17:53)
таки ты хочешь сказать, что система обо мне сама позаботится, сбой произойдет при FlushFileBuffers, то при сосстановлении система восстановит исходное значение файла?
Не верю, быть такого не может. А если файл 1гб?
Или ты что-то другое имел в виду?
← →
Sha © (2005-04-26 17:58) [93]alpet © (26.04.05 17:44) [89]
Возможны 3 состояния:
a) есть только файл data.txt,
б) есть файл data.txt и data.tmp,
в) есть только файл data.tmp.
В случаях а) и б) - правильный файл data.txt.
В случае в) - правильный файл data.tmp. Переименовываем и продолжаем работать.
← →
alpet © (2005-04-26 18:02) [94]Sha © (26.04.05 17:58) [93]
Четвертое состояние:
г) Есть только файл data.txt но он безнадежно поврежден.
Как быть?
← →
Sha © (2005-04-26 18:19) [95]> Суслик © (26.04.05 17:57) [92]
Эксперимент (на W2K) подтверждает, что FlushFileBuffers - синхронная операция, и управление к тебе не вернется до завершения записи данных и метаданных на диск:
procedure TSenderForm.Button1Click(Sender: TObject);
var
fi: file;
i: integer;
s: string;
begin
SetLength(s,1024);
AssignFile(fi,"aaa"); Rewrite(fi,1);
for i:=1 to 1024*1024 do BlockWrite(fi,s[1],Length(s));
FlushFileBuffers(TFileRec(fi).Handle);
ShowMessage("ccc");
CloseFile(fi);
end;
Пускаем сие чудо, а файлик смотрим Far"ом.
> alpet © (26.04.05 18:02) [94]
> г) Есть только файл data.txt но он безнадежно поврежден.
наша приграмма ни при каких условиях сделать этого не могла.
← →
alpet © (2005-04-26 18:32) [96]Sha © (26.04.05 18:19) [95]
> наша приграмма ни при каких условиях сделать этого не могла.
Это понятно. Но другая программа вполне может повредить файл. И жесткий диск может внезапно осыпаться битыми кластерами.
← →
mgcr © (2005-04-26 18:47) [97]alpet © (26.04.05 18:32) [96]
А еще может случиться пожар и наводнение. Одновременно. Задача не стоит того флейма.
← →
Суслик © (2005-04-26 18:54) [98]
> [95] Sha © (26.04.05 18:19)
Таки что это доказывает?
Маленькое уточняющее резюме - ты считаешь, что функция flushFileBuffers будучи вызванной гарантирует, что файл будет записан даже если питание будет отключено? Запустался я что-то в высказываниях (((
> [97] mgcr © (26.04.05 18:47)
> Задача не стоит того флейма.
Предлагаю автору топика решать, что стоит его задача.
← →
alpet © (2005-04-26 18:55) [99]mgcr © (26.04.05 18:47) [97]
Ну стихийные бедствия я думаю нельзя предотвратить. Да и вирусов в порядке вещей повреждающих файлы мало. Так что с учетом отсутствия этих факторов, копии не нужны.
<offtop>
А какая тема - рекордсмен по количеству постов.
← →
Суслик © (2005-04-26 18:57) [100]В общем, ладно. Спасибо всем за участие к проблеме.
Завтра у меня будет тестовый комп с образами разных систем и разными файловыми системами. Потестирую методику:
1.Переименовывать файл "что-то.dat" в "что-то.old"
2.Писать в "что-то.dat"
3.Делать flushFileBuffers для "что-то.dat"
4.Потом удалять "что-то.old"
5.Если при загрузке системы есть "что-то.old", то был сбой.
Об успехах доложу:)
← →
alpet © (2005-04-26 19:02) [101]Суслик © (26.04.05 18:54) [98]
Если управление вернулось из функции - питание еще наличествует и файл уже на диске (на худой конец в кэше hdd). Если не вернулось (питание пропало или кто-то нажал Reset) - файл не записался до конца, при этом на диске он будет выглядеть либо как пустой, либо вообще отсутствовать.
Кстати выявляется вопрос - на сигнал Reset HDD сбрасывает аппаратный буфер или же записывает его на диск.
← →
Sha © (2005-04-26 19:05) [102]>Sha © (26.04.05 18:19) [95]
Вообще-то приведенный код не позволяет сделать
никаких выводов, т.к. Far получает уведомления с опозданием.
А если попробовать использовать FindFirst, то sr.Size
будет один и тот же независимо от вызова/невызова FlushFileBuffers, т.к. метаданные тоже кешируются.
В синхронность остается только верить...
← →
Sha © (2005-04-26 19:14) [103]> Суслик © (26.04.05 18:54) [98]
Точнее так:
на мой взгляд, для локального файла возрат из FlushFileBuffers гарантирует, что данные и метаданные будут записаны на диск даже если питание будет отключено до вызова CloseHandle.
← →
Суслик © (2005-04-26 19:24) [104]
> [103] Sha © (26.04.05 19:14)
т.е. отслюда следует вывод, что если я после возврата из flushFileBuffers удалю копию файла, то я гарантированно данные записал. Так?
Т.е. моя методика, описанная выше:
1.Переименовываю файл "что-то.dat" в "что-то.old"
2.Пишу в "что-то.dat"
3.Делаю flushFileBuffers для "что-то.dat"
4.Потом удалаю "что-то.old"
5.Если при загрузке системы есть "что-то.old", то был сбой. Тогда в качество "что-то.dat" нужно взять "что-то.old".
имеет правод на жизнь?
← →
Суслик © (2005-04-26 19:25) [105]
> [104] Суслик © (26.04.05 19:24)
Вернее не гаратированно не записал, а гарантированно не потерял.
← →
Sha © (2005-04-26 19:46) [106]> Суслик
> имеет право на жизнь?
Вроде имеет :)
Но получше будет так:
- писать что-то.tmp,
- удалять что-то.dat,
- переименовывать что-то.tmp в что-то.dat.
В этом случае время жизни "неправильного" имени меньше.
← →
Суслик © (2005-04-26 20:10) [107]
> - переименовывать что-то.tmp в что-то.dat.
ой боюсь я за эту операцию :)))
← →
Суслик © (2005-04-26 20:10) [108]правда она и у меня есть... так что может так и сделаю. Наверно лучше всего копировать файл, а не переименовывать. В этом случае вообще очень все надежно будет.
← →
Sha © (2005-04-26 21:23) [109]> Суслик © (26.04.05 20:10) [108]
> Наверно лучше всего копировать файл, а не переименовывать.
В подобных случаях всегда использую переименование,
даже для сетевых дисков. И быстрее, и надежнее.
Т.к. это атомарная операция, другое приложение никогда
не попытается работать с наполовину скопированным файлом.
← →
Суслик © (2005-04-27 01:11) [110]
> Sha © (26.04.05 21:23) [109]
При всем уважении, Саша, ты не писал систему - фиг ее знает, что тут атомарная операция, а что нет.
Я думаю, что лечше всего полагаться ни минимизирование (а не исключение) вероятности ошибки.
← →
Sha © (2005-04-27 09:36) [111]> Суслик © (27.04.05 01:11) [110]
В любой файловой системе переименование файла - атомарная операция.
← →
mgcr © (2005-04-28 10:20) [112]Суслик © (27.04.05 01:11) [110]
> Я думаю, что лечше всего полагаться ни минимизирование (а
> не исключение) вероятности ошибки.
Лучше каждый оператор с молитвой писать. Оно надежнее. А еще лучше - послушать или почитать умных людей. Они тебе вреда не хотят.
← →
Суслик © (2005-04-29 12:35) [113]
> В любой файловой системе переименование файла - атомарная
> операция.
верю :) Это документировано?
> [112] mgcr © (28.04.05 10:20)
хватит колкости говорить, я и тебя и Сашу слушаю, и не сомневаюсь в вашем уме.
← →
Sha © (2005-04-29 14:05) [114]> Суслик © (29.04.05 12:35) [113]
>> В любой файловой системе переименование файла - атомарная
>> операция.
> верю :) Это документировано?
А ты можешь представить себе наполовину переименованный файл? :)
← →
Суслик © (2005-04-29 15:41) [115]
> [114] Sha © (29.04.05 14:05)
"чудеса бывают"
(с) опытный программист (где-то вчера прочел)
Длинные строки в дельфи потокобезопасные. ДинМассивы тоже. Т.е. это значит, что строка не будет неконсистентной (с системной точки зрения) при многопоточном использовании - например, не оказется, что длина строки, одна а на самом деле выделено памяти другое количество. Также и с массивами.
Но это же ребята из борланда потрудились. Не сделай они этого - валились бы строки из нескольких потоков с нашими любимыми AV. Запросто.
Наверняка в файлах авторы тоже потрудились. Так, чтобы данные не смогли остаться неконсистентными при выключении. Весь вопрос - где про это написано.
← →
mgcr © (2005-04-29 15:46) [116]
> Весь вопрос - где про это написано.
Ты эта...не притворяйся write only, если не трудно. Пост № 13 прочитай.
← →
Суслик © (2005-04-29 15:49) [117]
> [116] mgcr © (29.04.05 15:46)
така вы не скажете где это написано?! (шутка, читать я тоже умею).
..........................
Списибо всем. Собираюсь купить указанную Игорем книгу.
← →
Sha © (2005-04-29 16:13) [118]> Суслик © (29.04.05 15:41) [115]
> Весь вопрос - где про это написано.
Цитата из неизданного MS:
Предостередение.
Операция переименования файла в пределах одного каталога
относится к классу потенциально опасных.
Внезапное пропадание электропитания может привести к потере
файла или появлению второго имени у одних и тех же данных.
← →
Суслик © (2005-04-29 16:14) [119]
> [118] Sha © (29.04.05 16:13)
Шутка? Ей богу, юмор я люблю, но мне сейча не до него :)
← →
Sha © (2005-04-29 16:25) [120]Цитата из неизданного MS.
Страницы: 1 2 3 4 вся ветка
Форум: "WinAPI";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];
Память: 0.69 MB
Время: 0.049 c