Error 32 (file is in use by another process) when renaming a file

rossmcm picture rossmcm · Aug 19, 2011 · Viewed 8.9k times · Source

I have a Delphi 2006 app that writes to a file and then regularly renames it to a sequenced name, and creates a new one, i.e.

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  
...

The problem is that occasionally the rename fails with Error 32 - The process cannot access the file because it is being used by another process. I am checking that the destination of the rename doesn't exist. It's as if the close of the file after writing a record doesn't happen immediately. I added a loop in the rename procedure to sleep for a bit and try again up to 10 times but that doesn't help.

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 ;

* ADDITIONAL INFO *

This is the ProcMon log of the relevant disk I/O, with the associated Pascal source or psuedo-code preceding each block

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

* UPDATE *

I think I have nailed it. I downloaded handle.exe and ran it. Process explorer always shows no handles matching APP.DAT, but the handle.exe utility showed a list of handles owned by PID 4 (System) with APP.DAT as the filename. What I hadn't mentioned in my OP was that the same app runs on another network machine in a secondary "monitor" mode where it doesn't write to the APP*.DAT files but only reads from them. The "aha!" moment was when I realised that the problem only occurred when the monitor app was also running, and that the handle leaks showed as belonging to the "System" process - which presumably created the handle when the file was opened from the network machine.

Occasionally the monitor app was denied access to the file (always with Error 998 - Invalid access to memory location - for some reason) and the error path did not close the handle. From that point on the primary instance of the app was still able to read and write the file APP.DAT but failed on the rename. Making sure the file was closed on the error seems to have fixed it.

The pointer to "handle.exe" was the key, along with the knowledge that I could still write to a file with another opened handle, but a rename would fail. Thanks to everyone for their contributions.

Answer

Nat picture Nat · Aug 19, 2011

It would appear to me that the problem is not the destination file, but the source file... Make sure the handle is closed on the source file, that's where your problem will be.