Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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.041 c
9-1111239509
Radgar
2005-03-19 16:38
2005.06.29
Как изменить разрешение монитора.


3-1115995250
Lex_!
2005-05-13 18:40
2005.06.29
TThread и работа с базой


9-1111516682
Sphinx
2005-03-22 21:38
2005.06.29
Плагин к 3DS Max 7 и .X файлы


11-1099285783
Cosim
2004-11-01 08:09
2005.06.29
Непечатные символы в RIchEdit-e


1-1117889389
Петр
2005-06-04 16:49
2005.06.29
Утечка памяти





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский