Python:Windows系统文件 [英] Python: Windows System File

查看:123
本文介绍了Python:Windows系统文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在python中,如何识别窗口系统文件"文件.从命令行,我可以使用以下命令执行此操作:

In python, how can I identify a file that is a "window system file". From the command line I can do this with the following command:

ATTRIB "c:\file_path_name.txt"

如果返回的字符带有"S"字符,则它是Windows系统文件.我无法弄清楚python中的等价物.几个类似查询的示例如下所示:

If the return has the "S" character, then it's a windows system file. I cannot figure out the equivilant in python. A few example of similar queries look like this:

文件可写吗?

import os

filePath = r'c:\testfile.txt'

if os.access(filePath, os.W_OK):
   print 'writable'
else:
   print 'not writable'

另一种方式...

import os
import stat

filePath = r'c:\testfile.txt'

attr = os.stat(filePath)[0]
if not attr & stat.S_IWRITE:
   print 'not writable'
else:
   print 'writable'

但是我找不到识别Windows系统文件的函数或枚举.希望有一种内置的方法可以做到这一点.我不想不必使用win32com或其他外部模块.

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. I'd prefer not to have to use win32com or another external module.

我要这样做的原因是因为我正在使用os.walk将文件从一个驱动器复制到另一个驱动器.如果有一种方法可以在忽略可能也起作用的系统文件的同时遍历目录树.

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.

感谢阅读.





这是我根据答案得出的解决方案:

Here's the solutions I came up with based on the answer:

使用win32api:

Using win32api:

import win32api
import win32con

filePath = r'c:\test_file_path.txt'

if not win32api.GetFileAttributes(filePath) & win32con.FILE_ATTRIBUTE_SYSTEM:
   print filePath, 'is not a windows system file'
else:
   print filePath, 'is a windows system file'

并使用ctypes:

import ctypes
import ctypes.wintypes as types

# From pywin32
FILE_ATTRIBUTE_SYSTEM = 0x4

kernel32dll = ctypes.windll.kernel32


class WIN32_FILE_ATTRIBUTE_DATA(ctypes.Structure):
   _fields_ = [("dwFileAttributes", types.DWORD),
               ("ftCreationTime", types.FILETIME),
               ("ftLastAccessTime", types.FILETIME),
               ("ftLastWriteTime", types.FILETIME),
               ("nFileSizeHigh", types.DWORD),
               ("nFileSizeLow", types.DWORD)]

def isWindowsSystemFile(pFilepath):
   GetFileExInfoStandard = 0

   GetFileAttributesEx = kernel32dll.GetFileAttributesExA
   GetFileAttributesEx.restype = ctypes.c_int
   # I can't figure out the correct args here
   #GetFileAttributesEx.argtypes = [ctypes.c_char, ctypes.c_int, WIN32_FILE_ATTRIBUTE_DATA]

   wfad = WIN32_FILE_ATTRIBUTE_DATA()
   GetFileAttributesEx(pFilepath, GetFileExInfoStandard, ctypes.byref(wfad))

   return wfad.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM

filePath = r'c:\test_file_path.txt'

if not isWindowsSystemFile(filePath):
   print filePath, 'is not a windows system file'
else:
   print filePath, 'is a windows system file'

我想知道在代码中粘贴常量"FILE_ATTRIBUTE_SYSTEM"是否合法,还是可以使用ctypes获取其值?

I wonder if pasting the constant "FILE_ATTRIBUTE_SYSTEM" in my code is legit, or can I get its value using ctypes as well?

推荐答案

但是我找不到识别Windows系统文件的函数或枚举.希望有一种内置的方法可以做到这一点.

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.

没有这样的事情. Python的文件抽象没有系统文件"的任何概念,因此它没有给您任何获取它的方法.同样,Python的stat是Microsoft C运行时库中的stat_stat函数的非常薄的包装,它没有任何系统文件"的概念.原因是Python文件和Microsoft的C库都被设计为非常类似于POSIX".

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".

当然,Windows 也具有完全不同的文件抽象.但是openstat等函数并未公开这一内容.而是有一组完全并行的函数,例如CreateFileGetFileAttributes等.如果需要这些信息,则必须调用这些函数.

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.

我不想不必使用win32com或其他外部模块.

I'd prefer not to have to use win32com or another external module.

好吧,您不需要win32com,因为这只是Windows API,而不是COM.

Well, you don't need win32com, because this is just Windows API, not COM.

但是win32api是最简单的方法.它为 GetFileAttributesEx ,这是您要调用的函数.

But win32api is the easiest way to do it. It provides a nice wrapper around GetFileAttributesEx, which is the function you want to call.

如果您不想使用外部模块,则始终可以通过 subprocess 来运行命令行工具(例如ATTRIB或者,如果您愿意,可以像DIR /S /A-S一样让Windows为您执行递归-跳过-跳过系统文件的工作……).

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…).

ctypes文档显示了如何调用Windows API函数,但这是第一次有些棘手.

The ctypes docs show how to call Windows API functions, but it's a little tricky the first time.

首先,您需要转到MSDN页面,以查找需要加载的DLL(内核32),函数是否具有单独的A和W变体(确实如此),以及要为任何常量传递的值(您可以必须访问另一个页面的链接,并了解C枚举的工作原理,以发现GetFileExInfoStandard为0),然后您需要弄清楚如何定义任何必需的struct.在这种情况下,如下所示:

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 structs necessary. In this case, something like this:

from ctypes import *
kernel = windll.kernel32

GetFileExInfoStandard = 0

GetFileAttributesEx = kernel.GetFileAttributesEx
GetFileAttributesEx.restype = c_int
GetFileAttributesEx.argypes = # ...

如果您真的想避免使用win32api,则可以自己完成ctypes包装器的工作.就个人而言,我会使用win32api.

If you really want to avoid using win32api, you can do the work to finish the ctypes wrapper yourself. Personally, I'd use win32api.

同时:

我要这样做的原因是因为我正在使用os.walk将文件从一个驱动器复制到另一个驱动器.如果有一种方法可以在忽略可能也起作用的系统文件的同时遍历目录树.

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.

在这种情况下,尤其是考虑到您抱怨检查每个文件太慢时,您可能也不想使用os.walk.而是使用 FindFirstFileEx ,然后手动执行递归.您可以区分文件和目录,而不必stat(或GetFileAttributesEx)每个文件(os.walk在后台进行),您可以直接在find函数中过滤掉系统文件,而不必每个stat文件等.

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.

同样,选项是相同的:如果想轻松使用,请使用win32api,否则请使用ctypes.

Again, the options are the same: use win32api if you want it to be easy, use ctypes otherwise.

但是在这种情况下,我来看一下Ben Hoyt的 betterwalk ,因为他已经完成了99%的ctypes包装,以及95%的其余代码.

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.

这篇关于Python:Windows系统文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆