Der schöne Günther 316 Posted September 24, 2019 I'm doing kiosk software that runs 24/7 and has to be able to cope with a sudden power loss. To get around the problem of corrupted local files, I usually Create a windows file handle with the flags FILE_FLAG_WRITE_THROUGH for a file like "config.ini.new" Pass that handle to a THandleStream, and save my content by SaveToStream(..) or whatever Call FlushFileBuffers(..) on that handle Close the windows file handle Atomically move "config.ini.new" to "config.ini" "Atomically move file" just boils down to procedure moveFileAtomic(const fromPath, toPath: String); const flags = MOVEFILE_REPLACE_EXISTING or MOVEFILE_WRITE_THROUGH; begin Win32Check( WinApi.Windows.MoveFileEx( PChar(fromPath), PChar(toPath), flags ) ); end; So far, everything was fine. Now I thought I was being smart and skipped step 1-4 by just using System.IoUtils.TFile.WriteAllText(filePath, fileContent). At one client with a power loss, that file ended up on disk, but just contained nullbytes. The WriteAllText method from Delphis library boils down to calling CreateFile(..) with FILE_ATTRIBUTE_NORMAL So basically what I guess must have happened: The file was not yet written do disk, and MoveFileEx moved something that wasn't even there yet. I cannot reproduce this by normally running software and not yanking the power cord out. My question is: What exactly was the cause? Was I missing FlushFileBuffers(HANDLE), was is that the original must have been created with FILE_FLAG_WRITE_THROUGH as well? Share this post Link to post
timfrost 78 Posted September 24, 2019 Take a look at SetFileInformationByHandle in MSDN. I have used it for a different purpose (moving a locked open file) but it seems to provide some other tricks which may (or may not) help you. Share this post Link to post