对隐藏文件进行跨平台处理的最佳方法是什么? (最好是在Python中,但其他解决方案仍然很受欢迎)
只需检查领先的'。'适用于* nix / Mac,文件属性适用于Windows。但是,这看起来有点简单,也没有考虑隐藏事物的替代方法(.hidden文件等)。有没有一种标准的方法可以解决这个问题?
答案 0 :(得分:19)
这是一个在Python 2.5+上运行的脚本,应该可以满足您的需求:
import ctypes
import os
def is_hidden(filepath):
name = os.path.basename(os.path.abspath(filepath))
return name.startswith('.') or has_hidden_attribute(filepath)
def has_hidden_attribute(filepath):
try:
attrs = ctypes.windll.kernel32.GetFileAttributesW(unicode(filepath))
assert attrs != -1
result = bool(attrs & 2)
except (AttributeError, AssertionError):
result = False
return result
我向jaraco.windows添加了与has_hidden_attribute类似的内容。如果你有jaraco.windows> = 2.3:
from jaraco.windows import filesystem
def has_hidden_attribute(filepath):
return filesystem.GetFileAttributes(filepath).hidden
正如Ben指出的那样,在Python 3.5上,你可以使用stdlib:
import os, stat
def has_hidden_attribute(filepath):
return bool(os.stat(filepath).st_file_attributes & stat.FILE_ATTRIBUTE_HIDDEN)
虽然您可能仍希望将jaraco.windows用于更多Pythonic API。
答案 1 :(得分:9)
Jason R. Coombs的答案足以满足Windows的需求。和大多数POSIX GUI文件管理器/打开对话框/等。可能遵循与ls
相同的“dot-prefix-means-hidden”约定。但不是Mac OS X.
至少有四种方法可以在Finder,文件打开面板等中隐藏文件或目录:
~/Library
隐藏在10.7+中,但不在10.6中。)尝试编写自己的代码来处理所有这些并不容易。而且你必须保持它最新的,因为我愿意打赌黑名单与大多数操作系统版本更改,查找信息最终将过时的去完全不支持,扩展属性,可以更广泛地比HFS +支持,...
但是如果您可以要求pyobjc
(已经包含在Apple最近提供的Python中,并且可以通过pip
安装),则可以调用Apple的代码:
import Foundation
def is_hidden(path):
url = Foundation.NSURL.fileURLWithPath_(path)
return url.getResourceValue_forKey_error_(None, Foundation.NSURLIsHiddenKey, None)[0]
def listdir_skipping_hidden(path):
url = Foundation.NSURL.fileURLWithPath_(path)
fm = Foundation.NSFileManager.defaultManager()
urls = fm.contentsOfDirectoryAtURL_includingPropertiesForKeys_options_error_(
url, [], Foundation.NSDirectoryEnumerationSkipsHiddenFiles, None)[0]
return [u.path() for u in urls]
这应该适用于OS X 10.6+上pyobjc支持的任何Python。如果您想要10.5或更早版本,目录枚举标志尚不存在,因此唯一的选择就是在contentsOfDirectoryAtPath_error_
上过滤诸如os.listdir
(或仅is_hidden
)之类的内容。
如果您必须在没有pyobjc
的情况下离开,则可以下拉到CoreFoundation
等效项,然后使用ctypes
。关键功能是CFURLCopyResourcePropertyForKey
is_hidden
和CFURLEnumeratorCreateForDirectoryURL
列出目录。
有关实施,请参阅http://pastebin.com/aCUwTumB。
我测试过:
它适用于每个(例如,它在10.8上跳过~/Library
,但在10.6上显示它)。
应适用于任何OS X 10.6+和任何Python 2.6+。如果您需要OS X 10.5,则需要使用旧的API(或os.listdir
)并过滤is_hidden
。如果您需要Python 2.5,请将bytes
检查更改为str
检查(当然会断开3.x),将with
更改为丑陋的try
/ {{1}或手动释放。
如果有人计划将此代码放入库中,我强烈建议您首先检查finally
(pyobjc
,如果您没有获得import Foundation
,则并且仅在ImportError
代码不可用时才使用。
最后一点:
有些寻找这个答案的人正试图重新发明他们不需要的轮子。
通常,当人们做这样的事情时,他们正在构建一个GUI,并希望例如向文件浏览器显示隐藏或显示隐藏文件的选项。许多流行的跨平台GUI框架(Qt,wx等)内置了这种支持。(而且,其中许多都是开源的,因此您可以阅读他们的代码以了解他们是如何做到的。)
这可能无法解答您的问题 - 例如,他们可能只是将“过滤器隐藏文件”标记传递给平台的本机文件 - 浏览器对话框,但您正在尝试构建一个控制台模式的文件浏览器并且可以'那样做。但如果确实如此,只需使用它。
答案 2 :(得分:3)
我们实际上是在我们编写的项目中解决这个问题。我们所做的是有一些不同的“隐藏文件检查器”,它们在主检查器中注册。我们通过这些文件来查看它是否应该被隐藏。
这些检查器不仅适用于不同的操作系统等,而且我们可以插入版本控制“忽略”文件,并通过glob或正则表达式插入可选的用户覆盖。
它主要取决于你所做的,但是以可插拔,灵活和可扩展的方式。
请参阅此处的源代码:https://bitbucket.org/aafshar/pida-main/src/tip/pida/services/filemanager/filemanager.py
答案 3 :(得分:0)
结合我以前的答案以及来自@abarnert的答案,我发布了jaraco.path 1.1,支持隐藏文件检测的跨平台支持。安装该软件包后,要检测任何文件的隐藏状态,只需调用is_hidden
:
from jaraco import path
path.is_hidden(file)
答案 4 :(得分:-3)
“有没有一种标准的方法可以解决这个问题?”是。使用标准(即POSIX兼容)操作系统。
由于Windows是非标准的 - 好 - 没有适用的标准。如果有的话不是很好吗?我感觉到你的痛苦。
你尝试做的任何跨平台的东西都会让Win32变得奇怪。
你的解决方案是 - 对于目前的状况 - 非常好。在未来的某个时候,Microsoft可能会选择编写符合POSIX标准的操作系统。在此之前,你正在应对这种情况。