隠しファイルをクロスプラットフォームで処理する最良の方法は何ですか? (できればPythonで、しかし他の解決策はまだ高く評価されています)
先頭の「.」をチェックするだけです。*nix/Mac で動作し、ファイル属性は Windows で動作します。ただし、これは少し単純化されているように見えます。また、物を隠す別の方法 (.hidden ファイルなど) についても説明していません。これに対処する標準的な方法はありますか?
隠しファイルをクロスプラットフォームで処理する最良の方法は何ですか? (できればPythonで、しかし他の解決策はまだ高く評価されています)
先頭の「.」をチェックするだけです。*nix/Mac で動作し、ファイル属性は Windows で動作します。ただし、これは少し単純化されているように見えます。また、物を隠す別の方法 (.hidden ファイルなど) についても説明していません。これに対処する標準的な方法はありますか?
これは、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_attribute に似たものを jaraco.windows に追加しました。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)
ただし、より Pythonic API を使用するには、jaraco.windows を引き続き使用することをお勧めします。
Jason R. Coombs の答えは、Windows には十分です。そして、ほとんどの POSIX GUI ファイル マネージャー/ダイアログを開く/など。おそらくls
. しかし、Mac OS X ではありません。
ファイルまたはディレクトリを Finder やファイルを開くパネルなどで非表示にするには、少なくとも 4 つの方法があります。
~/Library
10.7 以降では隠されていますが、10.6 では隠されていません)。そのすべてを処理する独自のコードを作成しようとするのは簡単ではありません。また、最新の状態に保つ必要があります。ほとんどの OS バージョンでブラックリストが変更されることは間違いありません。Finder Info は最終的に非推奨から完全にサポートされなくなり、拡張属性は HFS+ よりも広くサポートされる可能性があります。 、…</p>
しかし、必要に応じて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を参照してください。
私は以下でテストしました:
~/Library
それぞれで適切に機能します (たとえば、 10.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 など) の多くには、このサポートが組み込まれています。
それはあなたの質問に答えないかもしれません—例えば、プラットフォームのネイティブ ファイル ブラウザー ダイアログに「隠しファイルをフィルター処理する」フラグを渡しているだけかもしれませんが、コンソール モードのファイル ブラウザーを構築しようとしていて、それを行うことはできません。 . しかし、そうであれば、それを使用してください。
私たちは実際に、私たちが書いたプロジェクトでこれに対処しています。私たちが行っているのは、メイン チェッカーに登録されているさまざまな「隠しファイル チェッカー」です。各ファイルをこれらに渡し、非表示にするかどうかを確認します。
これらのチェッカーは、さまざまな OS などに対応するだけでなく、バージョン管理の「無視された」ファイルと、glob または正規表現によるオプションのユーザー オーバーライドにプラグインします。
それは主にあなたが行ったことに相当しますが、プラグイン可能で柔軟で拡張可能な方法です.
ここでソースコードを参照してください: https://bitbucket.org/aafshar/pida-main/src/tip/pida/services/filemanager/filemanager.py
以前の回答と @abarnert からの回答を取り入れて、隠しファイル検出のクロスプラットフォーム サポートを備えたjaraco.path 1.1をリリースしました。そのパッケージがインストールされている状態で、任意のファイルの隠し状態を検出するには、次のコマンドを呼び出すだけですis_hidden
。
from jaraco import path
path.is_hidden(file)
「これに対処する標準的な方法はありますか?」はい。標準 (つまり、POSIX 準拠) OS を使用します。
Windows は非標準であるため、適用可能な標準はありません。あったら最高じゃないですか。あなたの痛みが分かります。
そのようなクロスプラットフォームでやろうとすることはすべて、Win32の奇妙な点があります。
あなたの解決策は - 現在の状況では - 優れています。将来のある時点で、Microsoft は POSIX 準拠の OS を作成することを選択する可能性があります。それまでは、この状況にうまく対処しています。