Rename file without overwriting existing files

Steve D'Aprano steve+python at pearwood.info
Sat Feb 11 23:09:08 EST 2017


On Fri, 10 Feb 2017 12:07 am, eryk sun wrote:

> On Thu, Feb 9, 2017 at 11:46 AM, Steve D'Aprano
> <steve+python at pearwood.info> wrote:
>>
>> So to summarise, os.rename(source, destination):
>>
>> - is atomic on POSIX systems, if source and destination are both on the
>>   same file system;
>> - may not be atomic on Windows?
>> - may over-write an existing destination on POSIX systems, but not on
>>   Windows;
>> - and it doesn't work across file systems.
> 
> On Windows in 2.7 and prior to 3.3, os.rename will silently copy and
> delete when the destination isn't on the same volume. 


Will the copy overwrite an existing file?


> It may even 
> silently leave the original file in place in some cases -- e.g. when
> the file is read-only and the user isn't allowed to modify the file
> attributes.
> 
> If the destination is on the same volume, renaming should be atomic
> via the system calls NtOpenFile and NtSetInformationFile. Ultimately
> it depends on the file system implementation of
> IRP_MJ_SET_INFORMATION, FileRenameInformation [1].
> 
>> The link/unlink trick:
>> - avoids over-writing existing files on POSIX systems at least;
>> - but maybe not Windows?
> 
> This works for renaming files on Windows as long as the file system
> supports hard links (e.g. NTFS). It's not documented on MSDN, but
> WinAPI CreateHardLink is implemented by calling NtSetInformationFile
> to set the FileLinkInformation, with ReplaceIfExists set to FALSE, so
> it fails if the destination exists. Note that this does not allow
> renaming directories. See the note for FileLinkInformation [1]; NTFS
> doesn't allow directory hard links. But why bother with this 'trick'
> on Windows?

I don't know, that's why I'm asking for guidance. I don't have a Windows
system to test on.

On Windows, how would you implement a file rename (potentially across file
system boundaries) which will not overwrite existing files? Just by calling
os.rename()?



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.




More information about the Python-list mailing list