diff options
| author | Brian Rosner <brosner@gmail.com> | 2008-07-01 15:49:08 +0000 |
|---|---|---|
| committer | Brian Rosner <brosner@gmail.com> | 2008-07-01 15:49:08 +0000 |
| commit | 0e8710d5900a75b9a4a1caebb82c939896e99cff (patch) | |
| tree | f3db8fb3f6b932bfc48526a70c332efce66d5cac /django/core/files/move.py | |
| parent | 595e9191f519af9b1c0c4b657fd3923c0997938c (diff) | |
newforms-admin: Merged from trunk up to [7814].
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@7815 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/core/files/move.py')
| -rw-r--r-- | django/core/files/move.py | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/django/core/files/move.py b/django/core/files/move.py new file mode 100644 index 0000000000..66873d450c --- /dev/null +++ b/django/core/files/move.py @@ -0,0 +1,59 @@ +""" +Move a file in the safest way possible:: + + >>> from django.core.files.move import file_move_save + >>> file_move_save("/tmp/old_file", "/tmp/new_file") +""" + +import os +from django.core.files import locks + +__all__ = ['file_move_safe'] + +try: + import shutil + file_move = shutil.move +except ImportError: + file_move = os.rename + +def file_move_safe(old_file_name, new_file_name, chunk_size = 1024*64, allow_overwrite=False): + """ + Moves a file from one location to another in the safest way possible. + + First, try using ``shutils.move``, which is OS-dependent but doesn't break + if moving across filesystems. Then, try ``os.rename``, which will break + across filesystems. Finally, streams manually from one file to another in + pure Python. + + If the destination file exists and ``allow_overwrite`` is ``False``, this + function will throw an ``IOError``. + """ + + # There's no reason to move if we don't have to. + if old_file_name == new_file_name: + return + + if not allow_overwrite and os.path.exists(new_file_name): + raise IOError("Cannot overwrite existing file '%s'." % new_file_name) + + try: + file_move(old_file_name, new_file_name) + return + except OSError: + # This will happen with os.rename if moving to another filesystem + pass + + # If the built-in didn't work, do it the hard way. + new_file = open(new_file_name, 'wb') + locks.lock(new_file, locks.LOCK_EX) + old_file = open(old_file_name, 'rb') + current_chunk = None + + while current_chunk != '': + current_chunk = old_file.read(chunk_size) + new_file.write(current_chunk) + + new_file.close() + old_file.close() + + os.remove(old_file_name) |
