Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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
1-1116608902
френк
2005-05-20 21:08
2005.06.06
путь к сервису


14-1116515386
QuasiLamo
2005-05-19 19:09
2005.06.06
Актуальный список регионов и городов России


3-1114691689
zdn
2005-04-28 16:34
2005.06.06
TClientDataSet


14-1116517929
Andy BitOff
2005-05-19 19:52
2005.06.06
Моральная индульгенция


14-1116436236
Yegorchic
2005-05-18 21:10
2005.06.06
Статья про Photoschp CS





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