Kai*_*Kai 17 python filesystems cross-platform
对隐藏文件进行跨平台处理的最佳方法是什么?(最好是在Python中,但其他解决方案仍然很受欢迎)
只需检查一个领先的'.' 适用于*nix/Mac,文件属性适用于Windows.但是,这看起来有点简单,也没有考虑隐藏事物的替代方法(.hidden文件等).有没有一种标准的方法可以解决这个问题?
Jas*_*mbs 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
Run Code Online (Sandbox Code Playgroud)
我在jaraco.windows中添加了类似于has_hidden_attribute的东西.如果你有jaraco.windows> = 2.3:
from jaraco.windows import filesystem
def has_hidden_attribute(filepath):
return filesystem.GetFileAttributes(filepath).hidden
Run Code Online (Sandbox Code Playgroud)
正如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)
Run Code Online (Sandbox Code Playgroud)
虽然你可能仍然想使用jaraco.windows来获得更多的Pythonic API.
Jason R. Coombs的答案足以满足Windows的需求.和大多数POSIX GUI文件管理器/打开对话框/等.可能遵循相同的"dot-prefix-means-hidden"约定ls.但不是Mac OS X.
在Finder中可以隐藏文件或目录的至少四种方式,文件打开面板等:
~/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]
Run Code Online (Sandbox Code Playgroud)
这应该适用于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.
我测试过:
它适用于每个(例如,它跳过~/Library10.8,但在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你的胜利),并且只使用ctypes代码(如果它不可用).
最后一点:
一些寻找这个答案的人正试图重新发明他们不需要的轮子.
通常,当人们做这样的事情时,他们正在构建一个GUI,并希望例如向文件浏览器显示隐藏或显示隐藏文件的选项.许多流行的跨平台GUI框架(Qt,wx等)内置了这种支持.(而且,其中许多都是开源的,因此您可以阅读他们的代码以了解他们是如何做到的.)
这可能无法解答您的问题 - 例如,他们可能只是将"过滤器隐藏文件"标记传递给平台的本机文件 - 浏览器对话框,但您正在尝试构建一个控制台模式的文件浏览器而不能这样做.但如果确实如此,那就用吧.
我们实际上在我们编写的项目中解决了这个问题。我们所做的是拥有许多不同的“隐藏文件检查器”,它们注册到主检查器中。我们将每个文件传递给这些文件,看看是否应该隐藏它。
这些检查器不仅适用于不同的操作系统等,而且我们插入版本控制“忽略”文件,以及可选的用户通过 glob 或正则表达式覆盖。
它主要相当于您所做的事情,但以可插拔、灵活和可扩展的方式进行。
请参阅此处的源代码:https ://bitbucket.org/aafshar/pida-main/src/tip/pida/services/filemanager/filemanager.py
| 归档时间: |
|
| 查看次数: |
13981 次 |
| 最近记录: |