My windows program receives information from another program via directory/file interface. That is the other program drops files into a special directory. My program periodically scans the directory, finds the files, processes and then deletes them.
I use CreateFile() function to open such files. To ensure that the other program has finished writing to the file and closed it, I set the dwShareMode parameter to 0. If CreateFile fails with a sharing error I just skip the file until the next itteration.
The problem is that DeleteFile() fails with the ERROR_SHARING_VIOLATION error while the file is opened by my program.
I could close the file before deleteing it, but I would like to avoid the possibility of some other program opening the file just before I delete the file.
I use this code to open files
CreateFile(filePath,DELETE|FILE_READ_DATA,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)
Is it possible to achieve what I want: open the file exclusively an then delete it, so that no other program can interfere between openning and deleteting the file.
The actual object/file will be removed later by a GC when all references are gone.
If you delete it while it is written depending on the writing method, it will be either recreated with new data or space will continue to be written but the file won't be accessible. Third case, the file is written/closed on each new data block so then you will get "file not found" or other type of errors.
log itself not only won't do anything to actually free the disk space the file uses, the process will still write to the now-deleted file. rm only removes the file link from the directory. The file itself won't be deleted and its space freed until the process holding it open actually closes it.
FILE_FLAG_DELETE_ON_CLOSE is probably what are you looking for. From MSDN
*FILE_FLAG_DELETE_ON_CLOSE 0x04000000 - The file is to be deleted immediately after all of its handles are closed, which includes the specified handle and any other open or duplicated handles. If there are existing open handles to a file, the call fails unless they were all opened with the FILE_SHARE_DELETE share mode. Subsequent open requests for the file fail, unless the FILE_SHARE_DELETE share mode is specified.*
EDIT: added an example...
So, in you case you should:
HANDLE hFile = ::CreateFile(filePath,
DELETE|FILE_READ_DATA,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_DELETE_ON_CLOSE,
NULL);
//use the file...
::CloseHandle(hFile); //the file gets deleted when the handle is closed
Pass in FILE_SHARE_DELETE for dwShareMode. Note that this will still allow other applications (as well as your own) to call DeleteFile() while you are reading the file, but according to the documentation of DeleteFile() it won't be deleted until you call CloseHandle() to close your read handle.
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.
Other applications will not be able to read or write the file as long as you don't specify FILE_SHARE_READ or FILE_SHARE_WRITE respectively. Although with FILE_SHARE_DELETE then can move the file, but that would be it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With