I'm writing a backup script, which uses hard links to not consume space for unmodified files.
I'd like to check if a given file system (as determined from a specific directory) supports hard links at the start of the script - otherwise, it could get half-way through (copying multiple files) before the first hard link needs creating, causing the script drops out with an exception (which I could recover by reverting changes or silently changing hard links to full copies, but I don't really want either - I'd just rather not start if it's going to hit this issue).
So, how do I check if the file system supports hard links if the only available input is a string containing a directory location (eg "F:\\Backups"
or similar)?
F开发者_运维知识库ailing that, is there a nice way to check the type of file system that a particular directory is on?
I suppose could just pull that and then work out if it's supported or not from there?I'd tackle this problem this way: There are 3 alternatives for copying a file:
- On Unix, you can use
os.link
. On Windows, you can use a function like this:
def CreateHardLink(src, dst): import ctypes if not ctypes.windll.kernel32.CreateHardLinkA(dst, src, 0): raise OSError
(Disclaimer: I haven't tested it. The idea is to use the kernel32 API.)
- If all this fails, you can still make a regular file copy (for example, with
shutil.copy2
).
Then, you can test these 3 functions at the beginning of the script with a temporary file (to be deleted afterwards). The first of these 3 functions that succeeds (that is, the first one that raises no Exception
) is a good candidate for making the actual backup copies.
This idea follows a strategy pattern, where you have to select a function that takes the source and destination filenames and makes the best effort to make the copy the way you want it.
Let me add one more thing: Detecting the filesystem in order to choose a copying strategy is not a very good practice in the same way that detecting browsers is not a good practice to do different things in Javascript. It's always best to try to use a feature and be prepared to catch exceptions or handle errors in order to produce an alternative result.
精彩评论