Python: Windows System File
Solution 1:
But I can't find a function or enum to identify a windows system file. Hopefully there's a built in way to do this.
There is no such thing. Python's file abstraction doesn't have any notion of "system file", so it doesn't give you any way to get it. Also, Python's stat
is a very thin wrapper around the stat
or _stat
functions in Microsoft's C runtime library, which doesn't have any notion of "system file". The reason for this is that both Python files and Microsoft's C library are both designed to be "pretty much like POSIX".
Of course Windows also has a completely different abstraction for files. But this one isn't exposed by the open
, stat
, etc. functions; rather, there's a completely parallel set of functions like CreateFile
, GetFileAttributes
, etc. And you have to call those if you want that information.
I'd prefer not to have to use win32com or another external module.
Well, you don't need win32com
, because this is just Windows API, not COM.
But win32api
is the easiest way to do it. It provides a nice wrapper around GetFileAttributesEx
, which is the function you want to call.
If you don't want to use an external module, you can always call Windows API functions via ctypes
instead. Or use subprocess
to run command-line tools (like ATTRIB
—or, if you prefer, like DIR /S /A-S
to let Windows do the recursive-walk-skipping-system-files bit for you…).
The ctypes
docs show how to call Windows API functions, but it's a little tricky the first time.
First you need to go to the MSDN page to find out what DLL you need to load (kernel32), and whether your function has separate A and W variants (it does), and what values to pass for any constants (you have to follow a link to another page, and know how C enums works, to find out that GetFileExInfoStandard
is 0), and then you need to figure out how to define any struct
s necessary. In this case, something like this:
from ctypes import *
kernel = windll.kernel32
GetFileExInfoStandard = 0
GetFileAttributesEx = kernel.GetFileAttributesEx
GetFileAttributesEx.restype = c_int
GetFileAttributesEx.argypes = # ...
If you really want to avoid using win32api
, you can do the work to finish the ctypes
wrapper yourself. Personally, I'd use win32api
.
Meanwhile:
The reason I want to do this is because I am using os.walk to copy files from one drive to another. If there was a way to walk the directory tree while ignoring system files that may work too.
For that case, especially given your complaint that checking each file was too slow, you probably don't want to use os.walk
either. Instead, use FindFirstFileEx
, and do the recursion manually. You can distinguish files and directories without having to stat
(or GetFileAttributesEx
) each file (which os.walk
does under the covers), you can filter out system files directly inside the find function instead of having to stat
each file, etc.
Again, the options are the same: use win32api
if you want it to be easy, use ctypes
otherwise.
But in this case, I'd take a look at Ben Hoyt's betterwalk
, because he's already done 99% of the ctypes
-wrapping, and 95% of the rest of the code, that you want.
Post a Comment for "Python: Windows System File"