Форум: "WinAPI";
Текущий архив: 2005.06.06;
Скачать: [xml.tar.bz2];
ВнизРаботаю с файлом при помощи ф-ций FileOpen FileRead FileWrite Найти похожие ветки
← →
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.59 MB
Время: 0.012 c