2011-11-12 35 views
33

他のファイルがすでに存在する場合は、名前を変更してos.renameを上書きすることは可能ですか?たとえば、以下のコードでは、Tests.csvファイルがすでに存在する場合は、Tests.txtファイル(これもTests.csvという名前に変更されています)に置き換えられます。あなたがshutil.move()を試みることができるOs.Renameで強制上書きする

os.rename("C:\Users\Test.txt","C:\Users\Tests.csv"); 
+0

どのように第一の電位例外をキャッチ、ターゲットファイルをリンク解除についてはどうですか? –

+2

は常に文字列でバックスラッシュをエスケープすることを忘れないでください(例:使用 ' "C:\\ユーザー\\ Test.txtの"') – 6502

+1

...または 'R "C:\ユーザーは、Test.txtという\" を使用し、'、しかしには注意してくださいを'r" C:\\ "' –

答えて

24

from shutil import move 

move('C:\\Users\\Test.txt', 'C:\\Users\\Tests.csv') 

それともos.remove、その後shutil.move

from os import remove 
from shutil import move 

remove('C:\\Users\\Tests.csv') 
move('C:\\Users\\Test.txt', 'C:\\Users\\Tests.csv') 
+0

@ JohnZwinck:いいえ、これはWindows上で動作しますが、 'os.rename'は動作しません。 ['shutil.move'ソースコード](http://hg.python.org/cpython/file/9b26fa7f9adf/Lib/shutil.py#l298)を参照してください。 –

+1

これは現在の回答で私から+1されていますが、これは競合状態を引き起こす可能性があります。他の回答から、これはWindows上でやむを得ないことであることがわかります。 「存在している場合... ...」 –

+0

質問が尋ねるので、これは完全に間違っているので – denfromufa

0

標準ライブラリのドキュメントからは、「Windows上でdstが既に存在する場合、OSErrorのは次のようになりますそれがファイルであっても発生します。 DST名、既存のファイルのリネーム原子を実装する方法はありません「

http://docs.python.org/library/os.html#os.rename

だから、唯一の解決策は、残念ながら、オペレーティングシステムを変更することであろう。 Windowsでは、単に既存のファイルの上にrename()を挿入することはできません。

7

dstが存在し、ファイルである場合、ユーザーに許可があれば、自動的に置き換えられます。 srcとdstが異なるファイルシステム上にある場合、いくつかのUnixフレーバで操作が失敗することがあります。成功すると、名前の変更はアトミックな操作になります(これはPOSIXの要件です)。 Windowsでは、dstがすでに存在する場合、ファイルであってもOSErrorが発生します。 dstが既存のファイル名をとするときに、アトミックリネームを実装する方法がないかもしれません。 http://docs.python.org/library/os.html#os.rename

+6

Windowsは地球から追放しなければならないもう一つの理由をしようかと包まれるべきで削除 – MFB

+0

がかない、のMoveFile APIはアトミックであるロジック – paulm

2

十分おかしい、os.rename()のドキュメントは、それがUnixシステム上でターゲットを交換し言うが、Windows上でそれはしていません。デスティネーションがWindows上に存在する場合、アトムリネーミングを実装することは不可能であることについてあいまいに言及しています.IMOは、それをサポートしない理由はほとんどありません。

OSError(Windows上に存在する宛先)を捕捉して宛先を削除してから再試行する必要があります。 documentationとして

8

は、ファイルが潜在的なエラーを処理し、二重のステップos.remove + os.renameを自分で行うことを求めているので、どんなPythonがない存在する場合は、Windows上でアトミックリネーム動作を保証することは不可能だと言います。

UNIXシステムの場合、renameは、(操作がアトミックであることが保証されているため)存在する場合は上書きします。

Windowsでは、ファイルが使用中である可能性があるためにアクセス許可を持っていても、削除先ファイルを削除できないことに注意してください。これはWindowsファイルシステムのもう1つの重要な制限であり、コード内で自分で処理する必要があります。

19

のPython 3.3以降、標準のクロスプラットフォームソリューション、os.replace今そこにある:

は、DSTへ ファイルまたはディレクトリsrcを変更します。 dstがディレクトリの場合、OSErrorは になります。 dstが存在し、ファイルである場合、 ユーザに許可がある場合、サイレントに置き換えられます。srcとdstが異なるファイルシステムの にあると、操作が失敗することがあります。成功すると、名前変更はアトミック アトミックになります(これはPOSIX要件です)。

利用できる環境:Unix、Windowsの。バージョン3.3で

新しいです。

しかし、Windowsでは、それはアトミックであることは保証されていません(Python 3.4.4)。これは、internallyはWindows上でMoveFileExを使用しているため、このような保証はありません。

+0

MoveFileExはどのようにアトミックではありませんか?あなたはそのMSDNのページをチェックすると – paulm

+0

@paulmは、それが原子性を約束したことがないとさえ明示的に代替として 'MoveFileTransacted'を示唆しています。実際には、 'MoveFileEx'はローカルファイルシステム上ではアトミックですが、ネットワークファイルシステム上ではアトミックではありません(実際にはサーバに依存します)。しかし、ローカルFSesの場合でも、そのアトミック性は非契約的です。 – atzz

関連する問題