Ошибка 32 (файл используется другим процессом) при переименовании файла - PullRequest
2 голосов
/ 19 августа 2011

У меня есть приложение Delphi 2006, которое записывает в файл, а затем регулярно переименовывает его в последовательное имя и создает новое, т.е.

open file.dat
write a record to file.dat
close file.dat 
...   
open file.dat
write a record to file.dat
close file.dat  

rename file.dat to file20110818123456.dat

create file.dat

open file.dat
write a record to file.dat
close file.dat  
...

Проблема заключается в том, что иногда переименование завершается неудачно с помощью Error 32 - The process cannot access the file because it is being used by another process.Я проверяю, что пункт назначения переименования не существует.Как будто закрытие файла после записи записи происходит не сразу.Я добавил цикл в процедуру переименования, чтобы немного поспать и повторить попытку до 10 раз, но это не помогает.

function RenameFileAtAllCosts (const OldFileID : TFilename ;
                               const NewFileID : TFilename ;
                               out   ErrorCode : Integer) : boolean ;

const
    MaxRenameAttempts  = 10 ;

var
    RenameAttempts     : integer ;

begin
Result := FileExists (OldFileID) ;

if (Result = true) then
    begin
    if FileExists (NewFileID) then
        begin
        Result := DeleteFile (PChar (NewFileID)) ;
        end ;

    if (Result = true) then
        begin
        Result := (not FileExists (NewFileID)) ;
        end ;

    if (Result = true) then
        begin
        RenameAttempts := 0 ;
        repeat
            SysUtils.Sleep (50) ;   
            Result := RenameFile (OldFileID, NewFileID) ;
            inc (RenameAttempts)
        until (Result or (RenameAttempts >= MaxRenameAttempts)) ;
        end ;
    end ;
if (not Result) then
    begin
    ErrorCode := GetLastError ;
    end ;
end ;

* ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ *

Это журнал ProcMon соответствующего дискового ввода-вывода со связанным источником Pascal или псевдокодом, предшествующим каждому блоку.

open file.dat
write a record to file.dat
close file.dat 

5:45:27.1718325 PM  APP.exe 1276    CreateFile  C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Desired Access: Generic Read/Write, Disposition: Open, Options: Synchronous IO Non-Alert, Non-Directory File, Attributes: N, ShareMode: Read, Write, AllocationSize: n/a, OpenResult: Opened
5:45:27.1719739 PM  APP.exe 1276    QueryStandardInformationFile    C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS AllocationSize: 57,344, EndOfFile: 54,208, NumberOfLinks: 1, DeletePending: False, Directory: False
5:45:27.1720475 PM  APP.exe 1276    WriteFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Offset: 54,208, Length: 28, Priority: Normal
5:45:27.1721403 PM  APP.exe 1276    CloseFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS

if FileExists (NewFileID) then    // before call to RenameFileAtAllCosts
    begin

5:45:27.8630005 PM  APP.exe 1276    CreateFile  C:\Users\Public\Documents\APP\Datafile\APP20110819054527.DAT    NAME NOT FOUND  Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a

if DeleteFile (NewFileID) then    // before call to RenameFileAtAllCosts
    begin

5:45:27.8634050 PM  APP.exe 1276    CreateFile  C:\Users\Public\Documents\APP\Datafile\APP20110819054527.DAT    NAME NOT FOUND  Desired Access: Read Attributes, Delete, Disposition: Open, Options: Non-Directory File, Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a

Result := FileExists (OldFileID) ;

5:45:27.8640878 PM  APP.exe 1276    CreateFile  C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened
5:45:27.8641684 PM  APP.exe 1276    QueryBasicInformationFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS CreationTime: 2/08/2011 7:45:59 PM, LastAccessTime: 19/08/2011 4:25:33 PM, LastWriteTime: 19/08/2011 5:45:27 PM, ChangeTime: 19/08/2011 5:45:27 PM, FileAttributes: A
5:45:27.8641902 PM  APP.exe 1276    CloseFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS

    if FileExists (NewFileID) then
        begin  

5:45:27.8648698 PM  APP.exe 1276    CreateFile  C:\Users\Public\Documents\APP\Datafile\APP20110819054527.DAT    NAME NOT FOUND  Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a


    if (Result = true) then
        begin
        Result := (not FileExists (NewFileID)) ;
        end ;

5:45:27.8656780 PM  APP.exe 1276    CreateFile  C:\Users\Public\Documents\APP\Datafile\APP20110819054527.DAT    NAME NOT FOUND  Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a

        RenameAttempts := 0 ;
        repeat
            SysUtils.Sleep (50) ;   
            Result := RenameFile (OldFileID, NewFileID) ;
            inc (RenameAttempts)
        until (Result or (RenameAttempts >= MaxRenameAttempts)) ;

5:45:27.9211195 PM  APP.exe 1276    CreateFile  C:\Users\Public\Documents\APP\Datafile\APP.DAT  SHARING VIOLATION   Desired Access: Read Attributes, Delete, Synchronize, Disposition: Open, Options: Synchronous IO Non-Alert, Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a
5:45:27.9834427 PM  APP.exe 1276    CreateFile  C:\Users\Public\Documents\APP\Datafile\APP.DAT  SHARING VIOLATION   Desired Access: Read Attributes, Delete, Synchronize, Disposition: Open, Options: Synchronous IO Non-Alert, Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a
5:45:28.0459285 PM  APP.exe 1276    CreateFile  C:\Users\Public\Documents\APP\Datafile\APP.DAT  SHARING VIOLATION   Desired Access: Read Attributes, Delete, Synchronize, Disposition: Open, Options: Synchronous IO Non-Alert, Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a
5:45:28.1084086 PM  APP.exe 1276    CreateFile  C:\Users\Public\Documents\APP\Datafile\APP.DAT  SHARING VIOLATION   Desired Access: Read Attributes, Delete, Synchronize, Disposition: Open, Options: Synchronous IO Non-Alert, Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a
5:45:28.1710646 PM  APP.exe 1276    CreateFile  C:\Users\Public\Documents\APP\Datafile\APP.DAT  SHARING VIOLATION   Desired Access: Read Attributes, Delete, Synchronize, Disposition: Open, Options: Synchronous IO Non-Alert, Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a
5:45:28.2335139 PM  APP.exe 1276    CreateFile  C:\Users\Public\Documents\APP\Datafile\APP.DAT  SHARING VIOLATION   Desired Access: Read Attributes, Delete, Synchronize, Disposition: Open, Options: Synchronous IO Non-Alert, Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a
5:45:28.2959037 PM  APP.exe 1276    CreateFile  C:\Users\Public\Documents\APP\Datafile\APP.DAT  SHARING VIOLATION   Desired Access: Read Attributes, Delete, Synchronize, Disposition: Open, Options: Synchronous IO Non-Alert, Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a
5:45:28.3584062 PM  APP.exe 1276    CreateFile  C:\Users\Public\Documents\APP\Datafile\APP.DAT  SHARING VIOLATION   Desired Access: Read Attributes, Delete, Synchronize, Disposition: Open, Options: Synchronous IO Non-Alert, Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a
5:45:28.4209304 PM  APP.exe 1276    CreateFile  C:\Users\Public\Documents\APP\Datafile\APP.DAT  SHARING VIOLATION   Desired Access: Read Attributes, Delete, Synchronize, Disposition: Open, Options: Synchronous IO Non-Alert, Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a
5:45:28.4834629 PM  APP.exe 1276    CreateFile  C:\Users\Public\Documents\APP\Datafile\APP.DAT  SHARING VIOLATION   Desired Access: Read Attributes, Delete, Synchronize, Disposition: Open, Options: Synchronous IO Non-Alert, Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a


open file.dat
write several records to file.dat
close file.dat 

5:45:28.4899722 PM  APP.exe 1276    CreateFile  C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Desired Access: Generic Read/Write, Disposition: Open, Options: Synchronous IO Non-Alert, Non-Directory File, Attributes: N, ShareMode: Read, Write, AllocationSize: n/a, OpenResult: Opened
5:45:28.4901002 PM  APP.exe 1276    QueryStandardInformationFile    C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS AllocationSize: 57,344, EndOfFile: 54,236, NumberOfLinks: 1, DeletePending: False, Directory: False
5:45:28.4901636 PM  APP.exe 1276    WriteFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Offset: 54,236, Length: 28, Priority: Normal
5:45:28.4902365 PM  APP.exe 1276    QueryStandardInformationFile    C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS AllocationSize: 57,344, EndOfFile: 54,264, NumberOfLinks: 1, DeletePending: False, Directory: False
5:45:28.4903031 PM  APP.exe 1276    WriteFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Offset: 54,264, Length: 28, Priority: Normal
5:45:28.4903517 PM  APP.exe 1276    QueryStandardInformationFile    C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS AllocationSize: 57,344, EndOfFile: 54,292, NumberOfLinks: 1, DeletePending: False, Directory: False
5:45:28.4905200 PM  APP.exe 1276    WriteFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Offset: 54,292, Length: 28, Priority: Normal
5:45:28.4905917 PM  APP.exe 1276    QueryStandardInformationFile    C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS AllocationSize: 57,344, EndOfFile: 54,320, NumberOfLinks: 1, DeletePending: False, Directory: False
5:45:28.4906633 PM  APP.exe 1276    WriteFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Offset: 54,320, Length: 28, Priority: Normal
5:45:28.4907120 PM  APP.exe 1276    QueryStandardInformationFile    C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS AllocationSize: 57,344, EndOfFile: 54,348, NumberOfLinks: 1, DeletePending: False, Directory: False
5:45:28.4907747 PM  APP.exe 1276    WriteFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Offset: 54,348, Length: 28, Priority: Normal
5:45:28.4908214 PM  APP.exe 1276    QueryStandardInformationFile    C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS AllocationSize: 57,344, EndOfFile: 54,376, NumberOfLinks: 1, DeletePending: False, Directory: False
5:45:28.4908841 PM  APP.exe 1276    WriteFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Offset: 54,376, Length: 28, Priority: Normal
5:45:28.4909308 PM  APP.exe 1276    QueryStandardInformationFile    C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS AllocationSize: 57,344, EndOfFile: 54,404, NumberOfLinks: 1, DeletePending: False, Directory: False
5:45:28.4909929 PM  APP.exe 1276    WriteFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Offset: 54,404, Length: 28, Priority: Normal
5:45:28.4910396 PM  APP.exe 1276    QueryStandardInformationFile    C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS AllocationSize: 57,344, EndOfFile: 54,432, NumberOfLinks: 1, DeletePending: False, Directory: False
5:45:28.4911023 PM  APP.exe 1276    WriteFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Offset: 54,432, Length: 28, Priority: Normal
5:45:28.4911491 PM  APP.exe 1276    QueryStandardInformationFile    C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS AllocationSize: 57,344, EndOfFile: 54,460, NumberOfLinks: 1, DeletePending: False, Directory: False
5:45:28.4912118 PM  APP.exe 1276    WriteFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Offset: 54,460, Length: 28, Priority: Normal
5:45:28.4912578 PM  APP.exe 1276    QueryStandardInformationFile    C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS AllocationSize: 57,344, EndOfFile: 54,488, NumberOfLinks: 1, DeletePending: False, Directory: False
5:45:28.4913206 PM  APP.exe 1276    WriteFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Offset: 54,488, Length: 28, Priority: Normal
5:45:28.4913673 PM  APP.exe 1276    QueryStandardInformationFile    C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS AllocationSize: 57,344, EndOfFile: 54,516, NumberOfLinks: 1, DeletePending: False, Directory: False
5:45:28.4914300 PM  APP.exe 1276    WriteFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Offset: 54,516, Length: 28, Priority: Normal
5:45:28.4914761 PM  APP.exe 1276    QueryStandardInformationFile    C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS AllocationSize: 57,344, EndOfFile: 54,544, NumberOfLinks: 1, DeletePending: False, Directory: False
5:45:28.4915388 PM  APP.exe 1276    WriteFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Offset: 54,544, Length: 28, Priority: Normal
5:45:28.4915855 PM  APP.exe 1276    QueryStandardInformationFile    C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS AllocationSize: 57,344, EndOfFile: 54,572, NumberOfLinks: 1, DeletePending: False, Directory: False
5:45:28.4916482 PM  APP.exe 1276    WriteFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Offset: 54,572, Length: 28, Priority: Normal
5:45:28.4916936 PM  APP.exe 1276    QueryStandardInformationFile    C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS AllocationSize: 57,344, EndOfFile: 54,600, NumberOfLinks: 1, DeletePending: False, Directory: False
5:45:28.4917570 PM  APP.exe 1276    WriteFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Offset: 54,600, Length: 28, Priority: Normal
5:45:28.4918043 PM  APP.exe 1276    QueryStandardInformationFile    C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS AllocationSize: 57,344, EndOfFile: 54,628, NumberOfLinks: 1, DeletePending: False, Directory: False
5:45:28.4919003 PM  APP.exe 1276    WriteFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Offset: 54,628, Length: 28, Priority: Normal
5:45:28.4919483 PM  APP.exe 1276    QueryStandardInformationFile    C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS AllocationSize: 57,344, EndOfFile: 54,656, NumberOfLinks: 1, DeletePending: False, Directory: False
5:45:28.4920110 PM  APP.exe 1276    WriteFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Offset: 54,656, Length: 28, Priority: Normal
5:45:28.4920577 PM  APP.exe 1276    QueryStandardInformationFile    C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS AllocationSize: 57,344, EndOfFile: 54,684, NumberOfLinks: 1, DeletePending: False, Directory: False
5:45:28.4921205 PM  APP.exe 1276    WriteFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Offset: 54,684, Length: 28, Priority: Normal
5:45:28.4921672 PM  APP.exe 1276    QueryStandardInformationFile    C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS AllocationSize: 57,344, EndOfFile: 54,712, NumberOfLinks: 1, DeletePending: False, Directory: False
5:45:28.4922299 PM  APP.exe 1276    WriteFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS Offset: 54,712, Length: 28, Priority: Normal
5:45:28.4922843 PM  APP.exe 1276    CloseFile   C:\Users\Public\Documents\APP\Datafile\APP.DAT  SUCCESS

* ОБНОВЛЕНИЕ *

Я думаю, что прибил это.Я скачал handle.exe и запустил его.Обозреватель процессов всегда показывает отсутствие дескрипторов, соответствующих APP.DAT, но утилита handle.exe отображала список дескрипторов, принадлежащих PID 4 (System) с APP.DAT в качестве имени файла.То, что я не упомянул в моем OP, это то, что то же приложение работает на другом сетевом компьютере в режиме вторичного «монитора», когда оно не записывает в файлы APP * .DAT, а только читает из них.Ага!В тот момент я понял, что проблема возникает только тогда, когда приложение монитора также запущено, и что утечки дескриптора показываются как принадлежащие процессу «Система», который предположительно создал дескриптор, когда файл был открыт с сетевого компьютера.

Иногда приложению монитора было отказано в доступе к файлу (всегда с ошибкой 998 - неверный доступ к ячейке памяти - по некоторым причинам), и путь ошибки не закрывал дескриптор.С этого момента первичный экземпляр приложения все еще мог читать и записывать файл APP.DAT, но не смог переименовать.Проверка того, что файл был закрыт, ошибка, похоже, исправила его.

Ключом был указатель на «handle.exe», а также знание того, что я все еще могу записать файл с другим открытым дескриптором,но переименовать не удастся.Спасибо всем за их вклад.

Ответы [ 5 ]

4 голосов
/ 19 августа 2011

Полезный способ отладки таких проблем (для меня в любом случае) - поиск по имени файла с помощью функции «Найти / найти дескриптор или DLL» в Process Explorer.Если определенное имя файла открыто и эксклюзивно, оно покажет, какая программа его держит.Если это ваше, вы можете проверить, закрывается ли ручка.Если не ваш, вам, возможно, придется либо просто написать небольшое ожидание (Windows иногда тратит время, чтобы разобраться с вещами), либо принудительно разблокировать файл (у меня есть небольшая программа, которая делает это с EXPLORER.EXE, потому чтодержите блокировки файлов, когда я его использую).

HTH.

4 голосов
/ 19 августа 2011

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

1 голос
/ 19 августа 2011

Держу пари, что ваш вызов GetLastError возвращает код ошибки для более раннего вызова API, не связанного с этой процедурой.Насколько я могу вспомнить (где нет источника) FileExists не устанавливает код ошибки.Но если первый вызов FileExists завершится неудачно, вы все равно вызовете GetLastError.

0 голосов
/ 19 августа 2011

Стоит отметить, что файлы .DAT проверяются некоторыми антивирусными программами. Поэтому вы можете обнаружить, что закрываете файл, затем AV открывает его для сканирования, и, хотя он все еще остается открытым, вы пытаетесь обработать его. Конечно, вы не можете, так как AV имеет его открытым.

0 голосов
/ 19 августа 2011

Поможет ли вам повторить попытку переименования через секунду или около того?Возможно, Windows слишком медленная, чтобы ее догнать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...