Форум: "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 наводит на мысль что появляется еще один дескриптор файла (хотя его может создать разве что вирь, поставивший хук).
← →
mgcr © (2005-04-15 19:49) [41]Набережных С. © (15.04.05 16:48) [32]
> Это цитата, видимо, из дельфийского Win32 SDK? Не пользуйся
> им, не надо.
Спасибо. Я не буду пользоваться Win32 SDK. Но ты, если не трудно, читай свою цитату внимательно и найди 10 отличий от моей (кстати, источник моей - Platform SDK январь 2005),
В 2004 написано:
"The system is to open the file with no system caching. This flag has no effect on hard disk 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. Also, the file metadata may still be cached. To flush the metadata to disk, use the FlushFileBuffers function."
И далее, про те самые requirements.
> Рихтер, кстати, с MSDN согласен. Ну и я с ними за компанию:)
Я, Сергей, предпочитаю соглашаться с Руссиновичем и братом его во Христе, Соломоном :)
старый маразматикЪ (15.04.05 17:11) [35]
А ты, Паша, эта...попробуй так:
Handle := FileOpen (name, mode);
FileWrite (Handle, ....)
...
FileClose(Handle);
DeleteFile(Name);
А то я, честно говоря, не знаю, какие грабли есть в Erase. И, кроме того, кругом написано, не смешивать FileXXXX функции и функции, которые работают через файловые переменные (AssignFile, Erase, Reset, Rewrite).
С наилучшими бестами и регардсами,
← →
Набережных С. © (2005-04-15 20:19) [42]
> mgcr © (15.04.05 19:49) [41]
Да, ты прав. Я действительно не вник в приведенную тобой цитату. А сейчас перечитал и увидел еще меньше оснований для твоего высказывания в [24]: "не судьба тебе с ним работать." Или я, может быть, неправильно тебя понял? Каким образом выделенная тобой фраза может помешать работать с файлами без задействования системного буфера? Если ты это имел в виду.
← →
mgcr © (2005-04-15 20:41) [43]Набережных С. © (15.04.05 20:19) [42]
> Или я, может быть, неправильно тебя понял? Каким образом
> выделенная тобой фраза может помешать работать с файлами
> без задействования системного буфера
Во фразе, честно говоря, я ошибся. Потому как после внимательного прочтении понял, что она, скорее всего, должна относиться к аппаратному кэшированию диска. И на старуху бывает проруха.
А под несудьбой я имел в виду, что для нормальной работы надо учитывать все те самые requirements, то есть, обмениваться буферами, кратными длине сектора, буфер располагать на границе страницы, и т.д.
В любом случае, мне слабо верится, что из-за системного кэша может возникать ошибка удаления файлов.
А для повышения надежности защиты от аппаратных сбоев можно посоветовать использовать флаг FILE_FLAG_WRITE_THROUGH (Instructs the system to write through any intermediate cache and go directly to disk.
If FILE_FLAG_NO_BUFFERING is not also specified, so that system caching is in effect, then the data is written to the system cache, but is flushed to disk without delay.)
Вроде, с записью все тоже самое, но колдовства с выравниванием и размерами буфера нету.
С наилучшими бестами и регардсами,
← →
Набережных С. © (2005-04-15 21:00) [44]
> И на старуху бывает проруха.
:))) Эт я по себе знаю:) Я и сам ту фразу сначала неправильно понял.
> для нормальной работы надо учитывать все те самые requirements,
> то есть, обмениваться буферами, кратными длине сектора,
> буфер располагать на границе страницы, и т.д.
Да ладно тебе, обычная работа, ничего сложного.
> В любом случае, мне слабо верится, что из-за системного
> кэша может возникать ошибка удаления файлов.
Мне тоже не очень. Хотя я могу, чисто теоретически, представить как такое может случиться, но в реальности этих догадок сомневаюсь. Я и заговорил-то об этом в ответ на вполне конкретный вопрос в [4], безотносительно к теме самой ветки. Чистый оффтоп:))
> А для повышения надежности защиты от аппаратных сбоев можно
> посоветовать использовать флаг FILE_FLAG_WRITE_THROUGH
Можно, но по моим наблюдениям без буферизации работает быстрее, а это важно, когда дело доходит до этих флагов, ИМХО. Когда речь только о надежности, то конечно.
Спокойной ночи!
← →
Cobalt © (2005-04-15 22:50) [45]2 старый маразматикЪ (15.04.05 17:11) [35]
Может, проблема в том, что файл занят БД?
Проверьте эту вероятность.
← →
GrayFace © (2005-04-16 19:30) [46]mgcr © (15.04.05 14:43) [15]
Да оно по времени не сильно занимает.
Запись по 4 байта вместо записи буфера - примерно в 30 раз дольше, чтение - примерно в 300. Если время важно, то это немалые цифры.
старый маразматикЪ (15.04.05 17:11) [35]
ну, я стараюсь себе на машину ничего лишнего не ставить. во избежание.
Во избежание чего? Переполнения диска? ;)
← →
mgcr © (2005-04-18 11:13) [47]GrayFace © (16.04.05 19:30) [46]
> Запись по 4 байта вместо записи буфера - примерно в 30 раз
> дольше, чтение - примерно в 300.
Влез ? Высказался ? Умница. А теперь читай ветку с самого начала и до конца. Можно два раза.
← →
GrayFace © (2005-04-18 13:04) [48]mgcr © (18.04.05 11:13) [47]
Влез ? Высказался ? Умница. А теперь читай ветку с самого начала и до конца. Можно два раза.
И что это, интересно, я в ней должен найти?
← →
старый маразматикЪ (2005-04-18 13:08) [49]
> mgcr © (15.04.05 19:49) [41]
ок, ща перепишу, Erase у меня от паскалевского прошлого осталось. но, по-идее, ничего такого критично быть не должно, поскоку файл к моменту вызова уже закрыт. кажется, шо закрыт. по крайней мере в ста других местах испоьзования этой ф-ции работает просто с песней, и не один год
насчет FILE_FLAG_WRITE_THROUGH
его как использовать? так:
FileOpen(FileName, Mode+ FILE_FLAG_WRITE_THROUGH);?
вроре работает, не ругается, а как дальше - покажет жизнь. через время. с FILE_FLAG_NO_BUFFERING не оч хочется, чужие исходники корячить, хотя я их и так уже изрядно того...
> Cobalt © (15.04.05 22:50) [45]
да не должен. я-ж закрываю табличку.
> GrayFace © (16.04.05 19:30) [46]
> Во избежание чего? Переполнения диска? ;)
а знаешь, что наличие нортона типа антивируса плохо сказывается на работе? вплоть до появления фиг знает каких ошибок. или ХП там. ух, это его "Восстановление системы", чтоб его! пока нашли, почему глюки сыплются.
← →
старый маразматикЪ (2005-04-18 13:13) [50]
> mgcr © (15.04.05 16:32) [30]
> А тот же каталог с такой тучей файлов через проводник удалить
> - проблем не будет ?
из проводника - на раз удаляется.
да, я тут не совсем понял. CreateFile() создает файл, а мне его просто открыть надо. так там параметры в FileOpen() совсем другие. FILE_FLAG_WRITE_THROUGH тудой, видимо, не подойдет?
← →
begin...end © (2005-04-18 13:27) [51]> старый маразматикЪ (18.04.05 13:13) [50]
> CreateFile() создает файл, а мне его просто открыть
> надо
Справку по CreateFile читали? Параметр dwCreationDistribution может быть равен OPEN_EXISTING.
> так там параметры в FileOpen() совсем другие.
> FILE_FLAG_WRITE_THROUGH тудой, видимо, не подойдет?
Не подойдёт. FileOpen открывает файл с атрибутом FILE_ATTRIBUTE_NORMAL, без флагов. См. исходник FileOpen.
← →
mgcr © (2005-04-18 13:28) [52]старый маразматикЪ (18.04.05 13:13) [50]
А ты, Паша, не ленись, загляни внутрь SysUtils.pas
function FileOpen(const FileName: string; Mode: LongWord): Integer;
const
AccessMode: array[0..2] of LongWord = (
GENERIC_READ,
GENERIC_WRITE,
GENERIC_READ or GENERIC_WRITE);
ShareMode: array[0..4] of LongWord = (
0,
0,
FILE_SHARE_READ,
FILE_SHARE_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE);
begin
Result := Integer(CreateFile(PChar(FileName), AccessMode[Mode and 3],
ShareMode[(Mode and $F0) shr 4], nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0));
end;
Вот ты свой вызов FileOpen и перепиши на CreateFile, чтобы с флагами работать.
А если из проводника дерево с кучей файлов удаляется, а из программы нет, то код программы в студию - мы и там бревен найдем.
← →
старый маразматикЪ (2005-04-18 14:29) [53]
> begin...end © (18.04.05 13:27) [51]
> mgcr © (18.04.05 13:28) [52]
шорт побъери! в хелп заглянул, а в исходник - не судьба была. тормозю непадецки. понедельник день тяжелый.
исходник удалялки, из библиотеки RX, FileUtil.pas
function ClearDir(const Path: string; Delete: Boolean): Boolean;
const
{$IFDEF WIN32}
FileNotFound = 18;
{$ELSE}
FileNotFound = -18;
{$ENDIF}
var
FileInfo: TSearchRec;
DosCode: Integer;
begin
Result := DirExists(Path);
if not Result then Exit;
DosCode := FindFirst(NormalDir(Path) + "*.*", faAnyFile, FileInfo);
try
while DosCode = 0 do begin
if (FileInfo.Name[1] <> ".") and (FileInfo.Attr <> faVolumeID) then
begin
if (FileInfo.Attr and faDirectory = faDirectory) then
Result := ClearDir(NormalDir(Path) + FileInfo.Name, Delete) and Result
else if (FileInfo.Attr and faVolumeID <> faVolumeID) then begin
if (FileInfo.Attr and faReadOnly = faReadOnly) then
FileSetAttr(NormalDir(Path) + FileInfo.Name, faArchive);
Result := DeleteFile(NormalDir(Path) + FileInfo.Name) and Result;
end;
end;
DosCode := FindNext(FileInfo);
end;
finally
FindClose(FileInfo);
end;
if Delete and Result and (DosCode = FileNotFound) and
not ((Length(Path) = 2) and (Path[2] = ":")) then
begin
RmDir(Path);
Result := (IOResult = 0) and Result;
end;
end;
ниче военного не наблюдаю. я-б понял, если вообще ничего не удалялось, а так - один подкаталог, причем пустой. бредятина та еще. и шо забавно, иногда они удаляются! нет стабильности в жизни
← →
mgcr © (2005-04-18 14:56) [54]Я вот таким вот пользуюсь, может, поможет
procedure Utils_DeleteDirectoryTree (Directory: PChar);
var
FindHandle: THandle;
FindData: WIN32_FIND_DATAA;
begin
if not Assigned(Directory) or (Directory[0] = #0) or
not SetCurrentDirectoryA (Directory) then
Exit;
FindHandle := FindFirstFileA ("*", FindData);
if FindHandle <> INVALID_HANDLE_VALUE then
repeat
if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY)
= 0 then begin
SetFileAttributesA (FindData.cFileName, FILE_ATTRIBUTE_NORMAL);
DeleteFileA (FindData.cFileName);
end else if (lstrcmpA (FindData.cFileName, ".") <> 0) and
(lstrcmpA (FindData.cFileName, "..") <> 0) then
Utils_DeleteDirectoryTree (FindData.cFileName);
until not FindNextFileA (FindHandle, FindData);
Windows.FindClose (FindHandle);
SetCurrentDirectoryA ("..");
SetFileAttributesA (Directory, FILE_ATTRIBUTE_NORMAL);
RemoveDirectoryA (Directory);
end;
← →
старый маразматикЪ (2005-04-18 15:27) [55]
> mgcr © (18.04.05 14:56) [54]
сенк, спробую. токо, все-же, интересена причина, почему такое может быть. дело не совсем в том, что не удалились, я это переживу как-нить, но неприятный осадок остается. мало-ли где это может боком вылезти. да, под ДОСом было все гораздо проще...
← →
begin...end © (2005-04-18 15:35) [56]> старый маразматикЪ (18.04.05 15:27) [55]
Можно ещё SHFileOperation попробовать.
← →
mgcr © (2005-04-18 15:42) [57]
> ниче военного не наблюдаю. я-б понял, если вообще ничего
> не удалялось, а так - один подкаталог, причем пустой. бредятина
> та еще. и шо забавно, иногда они удаляются! нет стабильности
> в жизни
Я бы, в случае подобной ситуации, нашпиговал бы код из Rx (да и свой тоже, который не мой, а из Platform SDK) всякими проверками и вызовами SysErrorMessage(GetLastError). Хотя бы знать, по какой причине тот или иной файл не удаляется. Так что если не поможет, советую вставить обильные вызовы SysErrorMessage(GetLastError) или RaiseLastWin32Error.
← →
старый маразматикЪ (2005-04-18 16:06) [58]
> begin...end © (18.04.05 15:35) [56]
шо эт за зверь такой? библиотека сторонних производителей? токды смысла особого нету
> mgcr © (18.04.05 15:42) [57]
да, вообще мысль... надо спробовать...
← →
begin...end © (2005-04-18 16:20) [59]> старый маразматикЪ (18.04.05 16:06) [58]
> шо эт за зверь такой?
Это API-функция. С её помощью можно, в частности, удалить папку, предварительно не очищая её самостоятельно. Я совсем не уверен, что она в данной ситуации поможет, но попробовать можно.
Код может быть примерно таким:uses ShellAPI;
function DeleteFolder(const Path: string; ToRecycleBin: Boolean = False): Boolean;
var
Structure: TSHFileOpStruct;
begin
try
ZeroMemory(@Structure, SizeOf(Structure));
with Structure do
begin
wFunc := FO_DELETE;
fFlags := FOF_NOCONFIRMATION + FOF_SILENT;
if ToRecycleBin then
fFlags := fFlags or FOF_ALLOWUNDO;
pFrom := PChar(Path + #0)
end;
Result := SHFileOperation(Structure) = 0
except
Result := False
end
end
Страницы: 1 2 вся ветка
Форум: "WinAPI";
Текущий архив: 2005.06.06;
Скачать: [xml.tar.bz2];
Память: 0.65 MB
Время: 0.015 c