Jason R. Coombs 的回答对于 Windows 来说已经足够了。和大多数 POSIX GUI 文件管理器/打开对话框/等。可能遵循与ls 相同的“点前缀表示隐藏”约定。但不是 Mac OS X。
在Finder、文件打开面板等中隐藏文件或目录的方法至少有四种:
- 点前缀。
- HFS+ 不可见属性。
- Finder 信息隐藏标志。
- 匹配 CoreFoundation 中内置的特殊黑名单(每个操作系统版本都不同,例如,
~/Library 在 10.7+ 中隐藏,但在 10.6 中不隐藏)。
尝试编写自己的代码来处理所有这些问题并不容易。而且你必须保持最新,因为我愿意打赌黑名单会随着大多数操作系统版本而改变,Finder Info 最终会从弃用变为完全不受支持,扩展属性可能比 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]
这应该适用于 pyobjc 支持的任何 Python,在 OS X 10.6+ 上。如果您想要 10.5 或更早版本,目录枚举标志尚不存在,因此唯一的选择是在 is_hidden 上过滤 contentsOfDirectoryAtPath_error_(或只是 os.listdir)之类的东西。
如果您必须在没有 pyobjc 的情况下过日子,您可以下拉到 CoreFoundation 等效项,然后使用 ctypes。关键功能是CFURLCopyResourcePropertyForKey 用于is_hidden 和CFURLEnumeratorCreateForDirectoryURL 用于列出目录。
请参阅http://pastebin.com/aCUwTumB 了解实现。
我已经测试过:
- 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 上显示它)。
它应该适用于任何 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/finally 或手动释放。
如果有人计划将此代码放入库中,我强烈建议首先检查pyobjc(import Foundation,如果您没有获得ImportError,您就赢了),并且只使用@987654347 @code 如果它不可用。
最后一点:
一些寻找这个答案的人正试图重新发明一个他们不需要的轮子。
通常,当人们在做这样的事情时,他们正在构建一个 GUI,并希望,例如,显示一个文件浏览器,并带有隐藏或显示隐藏文件的选项。许多流行的跨平台 GUI 框架(Qt、wx 等)都内置了这种支持。(而且,其中许多是开源的,因此您可以阅读他们的代码以了解他们是如何做到的。)
这可能无法回答您的问题 - 例如,他们可能只是将“过滤隐藏文件”标志传递给平台的本机文件浏览器对话框,但您正在尝试构建控制台模式文件浏览器并且可以'不要那样做。但如果是的话,就用它吧。