how to determine if files are on same or different file systems
Peter Otten
__peter__ at web.de
Sun Dec 7 08:05:20 EST 2003
Kamus of Kadizhar wrote:
> Peter Otten wrote:
>
>> No need to determine it beforehand, just try (untested):
>>
>> def movefile(src, dst):
>> try:
>> os.rename(src, dst)
>> except OSError:
>> shutil.copy2(src, dst)
>> os.remove(src)
>>
>>
>> Of course, if you are using Python 2.3 you should use shutil.move() as
>> pointed out by Serge Orlov; the above was mostly posted to illustrate the
>> popular concept "It's easier to ask forgiveness than permission", i. e.
>> with Python's powerful exception handling mechanism you need not fear the
>> failure of a particular code snippet, as long as you provide the
>> appropriate error handling.
>
> Peter:
>
> I am copying 600mb - 1.2gb files over slow wireless to an NFS mount -
> not exactly the model of reliability. It takes 40 minutes to an hour to
> copy one of these. I am paranoid of failures - I don't want to lose
> movies.
>
> So, I don't want to rely on innate error handling, because the failure
> could come from wireless failure, and the copy could fail as well.
> That's why I'm looking for a way to tell if a particular partition is
> network mounted.
>
> The basic idea is that movies get moved on the same partition, but
> copied (and not deleted) when moving between network mounted partitions
> and local partitions. Deletes will be subject to manual review until I
> get a comfort factor.
>
I still think that EAFP
try:
os.rename(src, dst)
except OSError:
# any error here will still result in a traceback
# if not handled in client code
shutil.copy2(src, dst)
# os.remove() ommitted intentionally
is superior style to LBYL (look before you leap)
if isSamePartition(src, dst):
os.rename(src, dst)
else:
shutil.copy2(src, dst)
and fail to see the increased danger for your data. Plus, it saves you from
writing the nonexistent isSamePartition() :-)
Maybe you could replace the copy2() call with the invocation of some utility
that reliably copies over an unreliable connection (maybe can someone else
come up with a name), or you take the extra amount of work/time and compare
the two files after you have copied them.
>>
>> Random remarks:
>> - You might take a look at os.path.join()
>> - Ok, this is paranoia, but I would ensure that ".avi" is only at the end
>> of the string
>
> ".avi$" ? I still haven't figured out Python's string handling really
> well. Or use the length of the string and count backwards? I admit, I
> got lazy on this one.
Use regular expressions only as a last resort.
>>> import os
>>> path = "/dir/name.ext"
>>> os.path.splitext(path)
('/dir/name', '.ext')
Putting it into a function:
>>> def changeext(path, newext=""):
... return os.path.splitext(path)[0] + newext
...
>>> changeext("/sowhat/movie.mpg", ".jpg")
'/sowhat/movie.jpg'
>>> changeext("/sowhat/movie.mpg")
'/sowhat/movie'
>>> changeext("/sowhat/movie", ".jpg")
'/sowhat/movie.jpg'
I you want to do it only with string methods:
>>> path = "/one/two.three"
>>> path[:path.rindex(".")] + ".four"
'/one/two.four'
However, you would have to ensure that the dot position is after the last
slash.
For a quick overview what is available for strings:
>>> dir(str)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__',
'__ge__', '__getattribute__', '__getitem__', '__getnewargs__',
'__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__',
'__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__',
'__str__', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith',
'expandtabs', 'find', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower',
'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip',
'replace', 'rfind', 'rindex', 'rjust', 'rstrip', 'split', 'splitlines',
'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
Peter
More information about the Python-list
mailing list