Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2005.06.06;
Скачать: [xml.tar.bz2];

Вниз

Работаю с файлом при помощи ф-ций FileOpen FileRead FileWrite   Найти похожие ветки 

 
старый маразматикЪ   (2005-04-15 11:18) [0]

Win2000Pro и иногда возникает ситуация, когда я файл закрываю, чтобы потом удалить, а винда говорит, что он не закрыт, не могу удалить(в 98 такого не было). или держит в буфере до последнего, и в случае отключения питания или перезагрузки последние изменения пропадают(иногда достаточно значительные), вместо них пишется просто кусок покореженной памяти.
может, кто встречался с таким, как бороться? ведь если я говорю FileWrite, то, по идее, я уверен, что данные записаны, однако это не так. они в буфере. и запишутся наверняка, если я открою этот-же файл из другого процесса.


 
Alex Konshin ©   (2005-04-15 11:21) [1]

Раз говорит, что не закрыт, значит, не закрыт.
А ошибка у тебя в 17 строке.


 
старый маразматикЪ   (2005-04-15 11:45) [2]


> Alex Konshin ©   (15.04.05 11:21) [1]

конгениально! а я-то думаю... и про 17-ю строку - очень смешно. аж сполз под стол


 
Alex Konshin ©   (2005-04-15 12:12) [3]

Хм... Эта шутка явно не старее старого маразматика, хотя и ходит еще со времен Фидо, т.е. ей не менее 10 лет.


 
старый маразматикЪ   (2005-04-15 12:21) [4]


> Alex Konshin ©   (15.04.05 12:12) [3]

я знаю эту шутку.
а более интересные мысли есть? как заставить винду данные не буферизировать, хотя-бы?


 
mgcr ©   (2005-04-15 12:28) [5]

Может его не только ты открыл ? Посмотри Process Explorer"ом


 
старый маразматикЪ   (2005-04-15 12:35) [6]


> mgcr ©   (15.04.05 12:28) [5]

я. и токо я. локально отлаживаю. не совсем шоб уж индеец. тем паче, что файл открываю в ексклюзивном режиме, для отсечения возможных непоняток. ест-но, я не напрямую эти ф-ции юзаю, там вокруг них оберка идет, но сводится, в итоге, к ним. вернее, к винде. насколько я понимаю.


 
Котик Бегемотик   (2005-04-15 12:36) [7]

может это ?
function FlushFileBuffers(hFile: THandle): BOOL; stdcall;


 
старый маразматикЪ   (2005-04-15 12:45) [8]


> Котик Бегемотик   (15.04.05 12:36) [7]

эта... надо спробовать. сенкс


 
mgcr ©   (2005-04-15 13:05) [9]

Котик Бегемотик   (15.04.05 12:36) [7]

FileClose вообще-то вызывает эту функцию. Это так, к слову.


 
Набережных С. ©   (2005-04-15 14:21) [10]


> ведь если я говорю FileWrite, то, по идее, я уверен, что
> данные записаны

Ну и зря.

> как заставить винду данные не буферизировать, хотя-бы

FILE_FLAG_NO_BUFFERING в CreateFile, но твоя проблема явно не здесь.


 
mgcr ©   (2005-04-15 14:32) [11]

Набережных С. ©   (15.04.05 14:21) [10]


> Ну и зря.


Почему зря ?


 
старый маразматикЪ   (2005-04-15 14:37) [12]


> mgcr ©   (15.04.05 13:05) [9]

дык, после каждого чиха файлом хлоп-хлоп делать - оно не то. время тоже критично


> Набережных С. ©   (15.04.05 14:21) [10]

дык, сам знаю, шо зря. неоднократно проверено.


> FILE_FLAG_NO_BUFFERING в CreateFile, но твоя проблема явно
> не здесь

а где? FlushFileBuffers поможет? поскоку реально мне эту фигню оттестить сложно. все достаточно непредсказуемо


 
Набережных С. ©   (2005-04-15 14:38) [13]


> mgcr ©   (15.04.05 14:32) [11]

Не совсем понял вопрос. Зря так думал потому, что данные буферизуются, если файл открыт с буферизацией. Эта информация не секретная. Именно поэтому и зря так думал. Ответил?


 
Набережных С. ©   (2005-04-15 14:40) [14]


> старый маразматикЪ   (15.04.05 14:37) [12]
> FlushFileBuffers поможет?

Должон, меня ни разу не подводил:) Но смотри [9].


 
mgcr ©   (2005-04-15 14:43) [15]

старый маразматикЪ   (15.04.05 14:37) [12]


> дык, после каждого чиха файлом хлоп-хлоп делать - оно не
> то. время тоже критично


Да оно по времени не сильно занимает. Насколько я понял, у тебя проблемы с тем, чтобы файл удалить, а незакрытый ты по-любому не удалишь.

А если питание вырубается и хрень пишется - ну эта...сам себе злобный буратино. Либо ставь УПС либо закрывай и переоткрывай файл после каждой записи.

Набережных С. ©   (15.04.05 14:38) [13]

Данные-то буферизуются. Но доступ к ним со любой стороны (хоть через файл, хоть через файл-маппинг) все равно идет через тот же буфер. Так что с точки зрения процессов данные после FileWrite записываются.


 
Набережных С. ©   (2005-04-15 14:51) [16]


> mgcr ©   (15.04.05 14:43) [15]

Ну правильно. Только это не гарантирует безопасность данных при внезапном вмшательстве Чубайса:) Вроде об этом говорилось в [0]:

> случае отключения питания или перезагрузки последние изменения
> пропадают(иногда достаточно значительные), вместо них пишется
> просто кусок покореженной памяти.

??

А "покореженный кусок" потому, что SetEndOfFile был выполнен.


 
mgcr ©   (2005-04-15 14:53) [17]

Набережных С. ©   (15.04.05 14:51) [16]

Я полагаю, буратинизм мы не рассматриваем ? :) На этот случай тоже дана рекомендация :) Если злоумышленник нажмет reset на корпусе, тоже ведь не убережешься.


 
Набережных С. ©   (2005-04-15 14:58) [18]


> mgcr ©   (15.04.05 14:53) [17]

Честно говоря, я тебя не что-то никак не пойму:( Я что-то неправильно сказал? Что именно?


 
ASMiD   (2005-04-15 14:59) [19]

А еще есть разница - куда писать. На хард - одно, на сетевой диск - совсем другое. И FlushFileBuffers не всегда помогает.


 
mgcr ©   (2005-04-15 15:20) [20]

Набережных С. ©   (15.04.05 14:58) [18]

Да я просто считаю, что по FileWrite данные записываются :) С точки зрения процесса. А так, конечно, спор пустой.


 
Набережных С. ©   (2005-04-15 15:24) [21]


> mgcr ©   (15.04.05 15:20) [20]
> Да я просто считаю, что по FileWrite данные записываются
>

Дык я вроде обратного и не говорил, записываются конечно, только далеко не всегда сразу на диск:)


 
mgcr ©   (2005-04-15 15:29) [22]

Набережных С. ©   (15.04.05 15:24) [21]

Вот и согласились :)


 
старый маразматикЪ   (2005-04-15 15:31) [23]


> Набережных С. ©   (15.04.05 14:40) [14]

понято. а если с таким флажком открыть "FILE_FLAG_NO_BUFFERING в CreateFile" буфера не будет вообще?

>А "покореженный кусок" потому, что SetEndOfFile был выполнен.
и что? это просто куски инфы с винта туда попадают? похоже, весьма похоже


> mgcr ©   (15.04.05 14:43) [15]


> ставь УПС либо закрывай и переоткрывай файл после каждой
> записи

мне не надо, но существует достаточно большая прослойка людей, кто не имеет таковой возможности - УПС. а переоткрывать - не все так просто. вокруг него оболочка, каторая может из-за переоткрытия изменица, ну и по сетке тоже не оч.


> ASMiD   (15.04.05 14:59) [19]

эх... по сетке... и сетки такие бывают кривые... сапожники собирали, да кривыми руками...


 
mgcr ©   (2005-04-15 15:38) [24]


> понято. а если с таким флажком открыть "FILE_FLAG_NO_BUFFERING
> в CreateFile" буфера не будет вообще?


не судьба тебе с ним работать.

"The system is to open the file with no system caching. This flag has no effect on hard disk caching"

"An application must meet certain requirements when working with files opened with FILE_FLAG_NO_BUFFERING:

File access must begin at byte offsets within the file that are integer multiples of the volume"s sector size.
File access must be for numbers of bytes that are integer multiples of the volume"s sector size. For example, if the sector size is 512 bytes, an application can request reads and writes of 512, 1024, or 2048 bytes, but not of 335, 981, or 7171 bytes.
Buffer addresses for read and write operations should be sector aligned (aligned on addresses in memory that are integer multiples of the volume"s sector size). Depending on the disk, this requirement may not be enforced"

Оно тебе сильно надо ?


 
старый маразматикЪ   (2005-04-15 16:01) [25]


> mgcr ©   (15.04.05 15:38) [24]

опа! действительно... надо было мне сперва хелп почитать.

ладно,  с этим более-менее понятно, спасибо всем. хотя, если учитывать [19], то тоже не очень-то выход. клиент-сервер в руки, как говорится

а как быть с этим? конечно, там не совсем так, но сводится к такому:

FileOpen(fmOpenReadWrite+ fmShareExclusive)
******* чего-то делаю, потом подряд
FileClose()
DeleteFile() - а вот тут получаю отлуп. поричем, не всегда. а как карта ляжет. плавающее такое. иногда удается проскочить. такое ощущение, что система не успевает отработать закрытие файла. ему тудой Application.ProcessMessages натыкать? но это больше похоже на шаманские пляски с бубном


 
mgcr ©   (2005-04-15 16:12) [26]


> такое ощущение, что система не успевает отработать закрытие
> файла


А что говорит GetLastError ?

С бубном, конечно, плясать ни к чему. На всякий случай перед close попробуй вставить FlushFileBuffers (хотя это тоже бубен, только небольшой). У тебя часом файл не на сетевом диске, когда ты отлуп получаешь ?


 
старый маразматикЪ   (2005-04-15 16:27) [27]


> mgcr ©   (15.04.05 16:12) [26]

локально. это у меня утилитка, так, для себя. а чего говорит? файл заблокирован, говорит. правда интересно? нескоко раз сталкивался с такой лажей, когда директорию с поддиректориями и с файлами удаляю (порядка штуки файлов). стандартная ф-ция на рекурсии. так вот, иногда (!) нескоро поддиректорий остаются, поскоку там файлик лежит. а бывает и не лежит, просто пустая директория. мимо проскочили.


 
alpet ©   (2005-04-15 16:27) [28]

The DeleteFile function marks a file for deletion on close. Therefore, the file deletion does not occur until the last handle to the file is closed. Subsequent calls to CreateFile to open the file fail with ERROR_ACCESS_DENIED.

Я так понял, если файл открыт - он будет жить до тех пор пока его не закроет CloseHandle.

По сабжу - что за функция - FileOpen. Есть OpenFile но мелкомягкие не сильно рекомендуют ее использовать - дескать CreateFile лучше.


 
alpet ©   (2005-04-15 16:29) [29]

У OpenFile же параметры начинаются на OF_* и не совместимы с параметрами CreateFile.


 
mgcr ©   (2005-04-15 16:32) [30]


> По сабжу - что за функция - FileOpen


Sysutils.pas

старый маразматикЪ   (15.04.05 16:27) [27]

У тебя с системой все хорошо ? А то страсти рассказываешь. А тот же каталог с такой тучей файлов через проводник удалить - проблем не будет ?

И эта...может, код покажешь ?


 
alpet ©   (2005-04-15 16:33) [31]

Блин, понял - речь идет о RTL - функциях. Я же ими никогда не пользовался. Это просто оболочки для стандартных АПИ функций и нужны лишь в кросс-платформных проектах. Попробуй на чистом апи писать, может и всплывет твоя ошибка, или протрассировать эти функции.


 
Набережных С. ©   (2005-04-15 16:48) [32]


> mgcr ©   (15.04.05 15:38) [24]
> не судьба тебе с ним работать.

Это цитата, видимо, из дельфийского Win32 SDK? Не пользуйся им, не надо. У MSDN по этому поводу иное мнение:
Instructs the system to open the file with no intermediate buffering or caching. When combined with FILE_FLAG_OVERLAPPED, the flag gives maximum asynchronous performance, because the I/O does not rely on the synchronous operations of the memory manager. However, some I/O operations will take longer, because data is not being held in the cache.
An application must meet certain requirements when working with files opened with FILE_FLAG_NO_BUFFERING:

File access must begin at byte offsets within the file that are integer multiples of the volume"s sector size.
File access must be for numbers of bytes that are integer multiples of the volume"s sector size. For example, if the sector size is 512 bytes, an application can request reads and writes of 512, 1024, or 2048 bytes, but not of 335, 981, or 7171 bytes.
Buffer addresses for read and write operations should be sector aligned (aligned on addresses in memory that are integer multiples of the volume"s sector size). Depending on the disk, this requirement may not be enforced.
One way to align buffers on integer multiples of the volume sector size is to use VirtualAlloc to allocate the buffers. It allocates memory that is aligned on addresses that are integer multiples of the operating system"s memory page size. Because both memory page and volume sector sizes are powers of 2, this memory is also aligned on addresses that are integer multiples of a volume"s sector size.

Извиняюсь за столь длинную цитату. Рихтер, кстати, с MSDN согласен. Ну и я с ними за компанию:)

> старый маразматикЪ   (15.04.05 15:31) [23]
> а если с таким флажком открыть "FILE_FLAG_NO_BUFFERING в
> CreateFile" буфера не будет вообще?

Да.


 
alpet ©   (2005-04-15 16:57) [33]

Получается виндовсь заставляет контроллер жесткого диска сбрасывать буффер (аппаратный) в принудительном режиме?


 
Набережных С. ©   (2005-04-15 17:11) [34]

Кажется я вспомнил. Эта хрень была для 9х, там ни этот, ни FILE_FLAG_OVERLAPPED не работали, если не ошибаюсь.

> alpet ©   (15.04.05 16:57) [33]

Не знаю, возможно. А может, контроллер сам их сбрасывает по аварии питания. Но драйвер точно контроллеру сбрасывает.


 
старый маразматикЪ   (2005-04-15 17:11) [35]


> mgcr ©   (15.04.05 16:32) [30]

ну, я стараюсь себе на машину ничего лишнего не ставить. во избежание. голая винда, офис, по-минимуму короче. наблюдалось на 98 и 2000про. код...

на удаление файла, там не совсем DeleteFile(). в [25], но какая разница. надо-бы переписать, да лень, работает же. а если работает - лучше не трогать
procedure mDbfErase(Table: TDataSet);
var
 F: TextFile;
 TmpFileDbf: string;
begin
 try
   if Table.Active then table.Close;

   TmpFileDbf:= Table.DatabaseName+ "\"+ Table.tableName;
   if FileExists(TmpFileDbf) then
   begin
     AssignFile(F, TmpFileDbf);
     Erase(F);

     if FileExists(ChangeFileExt(TmpFileDbf, ".FPT")) then
     begin
       AssignFile(F, ChangeFileExt(TmpFileDbf, ".FPT"));
       Erase(F);
     end;
   end;
 except
//тута была-бы ошибка, но я ее ф сад, поскоку мне не критично, удалился или нет.
 end;
end;

а насчет очистки директории - стандартная из библиотеки RX
function ClearDir(), зачем выдумывать велосипед? хотя, потестить ее не мешало-бы. но уже в понедельник, ща мозги уже не варят. на предмет, какая ошибка там возникает. все атрибуты файлов отличные, никаких реадонлу или системных. последний запуск оставил пустой каталог с подкаталогом. бред. это, видать, карма плохая от ника передается бгы


> Набережных С. ©   (15.04.05 16:48) [32]

спасибо, я понял, но! меня смущает что на некоторых винтах работать не будет, это не подходит, у меня могут быть как раз такие... ну и выравнивание до размера сектора, как-то того... особливо по сетке, я там знаю, какой там сектор? лучше пока флушем попробую. а то потом меня ногами бить начнут, как все валится будет. хотя поэкспериментировать можно...


 
Набережных С. ©   (2005-04-15 17:41) [36]


> старый маразматикЪ   (15.04.05 17:11) [35]

Дык хозяин-барин:) Я вообще-то b не пытался никого убедить, что это наилучшее решение, каждому овощу - свое время. Скорее для общей информации высказался, ну и как ответ на твой прямой вопрос в [4]. В твоем случае, как и в большинстве, флаша вполне достаточно.

Ну а NO_BUFFERING я пользовался, и никаких сложностей, честно говоря, не заметил:) И с определением размера буфера тоже:)


 
старый маразматикЪ   (2005-04-15 18:38) [37]


> Набережных С. ©   (15.04.05 17:41) [36]

дык, я не против, надо токо будет поэксперементировать. наскоко я понял, мне нельзя записать инфу, меньшую размера сектора на диске, так? а как узнать, какой он на серваке? блок данных порезать на нужные куски можно будет, а потом в цикле... хотя, на производительности сетки это скажется не лучшим образом. фиг его знает...


 
Набережных С. ©   (2005-04-15 19:12) [38]


> мне нельзя записать инфу, меньшую размера сектора на диске,
> так?

Да, писать/читать нужно кратными блоками.

> а как узнать, какой он на серваке?

GetDiskFreeSpace. And VirtualAlloc for allocation.

> блок данных порезать на нужные куски можно будет

Зачем? Допустим, размер сектора 4Кб, а записать нужно 7500 байт. Значит нужно записать 8192 байт, а затем SetFilePointer and SetAndOfFile. Т.е. отрезать лишнее. Хотя иногда возможно лучше и порезать на какие-то блоки приемлемого размера.

Но, повторюсь, в твоем случае вряд-ли есть смысл это использовать. Будет достаточно FlushFileBuffers.


 
alpet ©   (2005-04-15 19:12) [39]

Насколько я понял этот параметр оказывает влияние только на локальный программный кеш (system cache / buffer). Стало быть функция CreateFile не в ответе за то что будет делать файловая система - отправлять данные на диск или в сеть (на диск сервера), и уж точно не гарантирует опустошение аппаратного буфера.
А на проблему описаную в сабже скорее влияет не буферризация.


 
alpet ©   (2005-04-15 19:24) [40]

Если вместо FileOpen указать:

CreateFile ("\autoexec.bat", GENERIC_WRITE, FILE_SHARE_DELETE, nil,
                               OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);


DeleteFile будет всегда отрабатываться успешно, но при этом файл реально удаляться будет только при закрытии его дескриптора.

Кстати использование fmShareExclusive наводит на мысль что появляется еще один дескриптор файла (хотя его может создать разве что вирь, поставивший хук).



Страницы: 1 2 вся ветка

Форум: "WinAPI";
Текущий архив: 2005.06.06;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.014 c
1-1116514312
Cat
2005-05-19 18:51
2005.06.06
число сделать наибольшим числом кратным 10.


14-1116641547
Jeka
2005-05-21 06:12
2005.06.06
Цифровой фотоаппарат


4-1113402764
_Okey_
2005-04-13 18:32
2005.06.06
Как изменить свойства обекта по ходу выполнения проги


1-1116609134
ancot
2005-05-20 21:12
2005.06.06
Количество элементов Set свойства


14-1116505335
XCept.ion
2005-05-19 16:22
2005.06.06
получение данных о погоде





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский