Python 跨平台隐藏文件检测
跨平台处理隐藏文件的最佳方法是什么? (最好使用Python,但仍欢迎使用其他解决方案) 只需检查前导“.”就可以用于*nix/Mac,文件属性在Windows上也可以。然而,这似乎有点简单,也没有考虑到隐藏东西的替代方法(.hidden files,等等)。有没有标准的方法来处理这个问题?“有没有标准的方法来处理这个问题?”是的。使用标准(即POSIX兼容)操作系统 因为Windows是非标准的,所以没有适用的标准。如果有,那不是很好吗?我感觉到你的痛苦 任何你试图做的跨平台的事情都会有Win32的奇怪之处Python 跨平台隐藏文件检测,python,cross-platform,filesystems,Python,Cross Platform,Filesystems,跨平台处理隐藏文件的最佳方法是什么? (最好使用Python,但仍欢迎使用其他解决方案) 只需检查前导“.”就可以用于*nix/Mac,文件属性在Windows上也可以。然而,这似乎有点简单,也没有考虑到隐藏东西的替代方法(.hidden files,等等)。有没有标准的方法来处理这个问题?“有没有标准的方法来处理这个问题?”是的。使用标准(即POSIX兼容)操作系统 因为Windows是非标准的,所以没有适用的标准。如果有,那不是很好吗?我感觉到你的痛苦 任何你试图做的跨平台的事情都会有Win
就目前的情况来看,你的解决方案非常好。在将来的某个时候,微软可能会选择编写一个兼容POSIX的操作系统。在那之前,你能很好地应对这种情况。我们实际上在我们编写的一个项目中解决了这个问题。我们所做的是有许多不同的“隐藏文件检查器”,它们在主检查器中注册。我们将每个文件传递给它们,以查看是否应该隐藏它 这些检查器不仅适用于不同的操作系统等,而且我们还插入了版本控制“忽略”文件,以及可选的用户覆盖glob或正则表达式 它主要相当于您所做的事情,但以一种可插拔、灵活和可扩展的方式
请参见此处的源代码:这是一个在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
我添加了类似于has_hidden_属性的内容。如果您的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来实现更具Python风格的API。Jason R.Coombs的答案对于windows来说已经足够了。大多数POSIXGUI文件管理器/打开对话框等可能遵循与
ls
相同的“点前缀表示隐藏”约定。但不是MacOSX
在查找器、文件打开面板等中隐藏文件或目录至少有四种方式:
- 点前缀
- HFS+不可见属性
- 查找信息隐藏标志
- 匹配CoreFoundation中内置的特殊黑名单(每个操作系统版本都不同,例如,
在10.7+中隐藏,但在10.6中不隐藏)~/Library
pyobjc
(它已经包含在最近苹果提供的Python中,并且可以通过pip
安装),您可以调用苹果的代码:
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]
这应该适用于pyobjc支持的任何Python,在OS X 10.6+上。如果您想要10.5或更早版本,目录枚举标志还不存在,因此唯一的选项是过滤上的目录路径\u错误\u(或仅os.listdir
)之类的内容
如果您必须在没有pyobjc
的情况下生存,您可以下拉到CoreFoundation
等价物,并使用ctypes
。关键函数是的cfurlcopyresourcepropertyworkey
和CFURLEnumeratorCreateForDirectoryURL
用于列出目录
有关实现,请参阅
我测试过:
- OS X 10.6,32位python.org 3.3.0
- OS X 10.8,32位Apple 2.7.2
- OS X 10.8,64位Apple 2.7.2
- OS X 10.8,64位python.org 3.3.0
它在每种情况下都能正常工作(例如,它在10.8中跳过~/Library
,但在10.6中显示)
它应该适用于任何OSX10.6+和任何Python 2.6+。如果您需要OSX10.5,则需要使用旧的API(或OS.listdir
)并在上进行筛选。如果您需要Python2.5,请将字节检查更改为str
检查(这当然会破坏3.x),并将的更改为丑陋的最后尝试/或手动释放
如果有人计划将此代码放入库中,我强烈建议首先检查pyobjc
(import Foundation
,如果没有ImportError
,则获胜),如果不可用,则仅使用ctypes
代码
最后一点注意:
一些寻找答案的人正试图重新发明一个他们不需要的轮子
通常,当人们在做类似的事情时,他们正在构建一个GUI,并希望(例如)在浏览器中显示一个带有隐藏或显示隐藏文件选项的文件。许多流行的跨平台GUI框架(Qt、wx等)都内置了这种支持。(此外,它们中的许多都是开源的,因此您可以阅读它们的代码来了解它们是如何做到的。)
这可能无法回答您的问题,例如,他们可能只是将“筛选隐藏文件”标志传递给平台的本机文件浏览器对话框,但您正在尝试构建控制台模式的文件浏览器,但无法做到这一点。但是如果有,就使用它。结合我之前的答案以及@abarnert的答案,我发布了对隐藏文件检测的跨平台支持。安装该软件包后,要检测任何文件的隐藏状态,只需调用is\u hidden
:
from jaraco import path
path.is_hidden(file)
@洛特:我通常喜欢你的评论,但这没有帮助。标准库中还有许多其他模块用于处理Windows的非标准方式。我肯定OP只是在寻找类似的东西。@TechnomalLogical:没错,有些模块可以最小化差异。关键是非标准意味着非标准。这是一个令人沮丧的问题。没有仙尘解决方案,mak