OSX HFS+ ファイルシステムに存在するファイルに関するデータを保存しています。後で保存されたデータを繰り返し処理し、各ファイルがまだ存在するかどうかを調べたいと思います。私の目的では、ファイル名の大文字と小文字の区別に注意を払っているため、ファイル名の大文字と小文字が変更された場合、ファイルはもう存在しないと見なします。
私は試してみることから始めました
os.path.isfile(filename)
ただし、HFS+ に OSX を通常インストールすると、ファイル名の大文字と小文字が一致しなくても True が返されます。ファイルシステムが大文字と小文字を区別しない場合でも、大文字と小文字を区別する isfile() 関数を作成する方法を探しています。
os.path.normcase() と os.path.realpath() はどちらもファイル名を返します。
編集:
現在、ASCII に限定されたファイル名で機能するように見える 2 つの関数があります。ユニコードやその他の文字がこれにどのように影響するかはわかりません。
1 つ目は、omz と Alex L による回答に基づいています。
def does_file_exist_case_sensitive1a(fname):
if not os.path.isfile(fname): return False
path, filename = os.path.split(fname)
search_path = '.' if path == '' else path
for name in os.listdir(search_path):
if name == filename : return True
return False
2 番目の方法は、おそらくさらに効率的ではありません。
def does_file_exist_case_sensitive2(fname):
if not os.path.isfile(fname): return False
m = re.search('[a-zA-Z][^a-zA-Z]*\Z', fname)
if m:
test = string.replace(fname, fname[m.start()], '?', 1)
print test
actual = glob.glob(test)
return len(actual) == 1 and actual[0] == fname
else:
return True # no letters in file, case sensitivity doesn't matter
これはDSMの回答に基づく3番目です。
def does_file_exist_case_sensitive3(fname):
if not os.path.isfile(fname): return False
path, filename = os.path.split(fname)
search_path = '.' if path == '' else path
inodes = {os.stat(x).st_ino: x for x in os.listdir(search_path)}
return inodes[os.stat(fname).st_ino] == filename
単一のディレクトリに何千ものファイルがある場合、これらがうまく機能するとは思いません。私はまだもっと効率的なものを望んでいます。
これらをテストしているときに気付いたもう 1 つの欠点は、ファイル名の大文字と小文字の一致のみをチェックすることです。ディレクトリ名を含むパスを渡すと、これまでのところ、これらの関数はどれもディレクトリ名の大文字と小文字をチェックしていません。