我正在存储有关 OSX HFS+ 文件系统上存在的文件的数据。我稍后想遍历存储的数据并确定每个文件是否仍然存在。出于我的目的,我关心文件名是否区分大小写,所以如果文件名的大小写发生了变化,我会认为该文件不再存在。
我开始尝试
os.path.isfile(filename)
但是在 HFS+ 上正常安装 OSX 时,即使文件名大小写不匹配,它也会返回 True。我正在寻找一种方法来编写一个关心大小写的 isfile() 函数,即使文件系统没有。
os.path.normcase() 和 os.path.realpath() 在我传入它们的任何情况下都返回文件名。
编辑:
我现在有两个似乎适用于仅限于 ASCII 的文件名的函数。我不知道 unicode 或其他字符如何影响这一点。
第一个是基于 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
第二个可能效率更低。
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
这是基于帝斯曼答案的第三个。
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
如果我在一个目录中有数千个文件,我不认为这些会表现良好。我仍然希望有一些感觉更有效的东西。
我在测试时注意到的另一个缺点是它们只检查文件名是否匹配。如果我向他们传递一个包含目录名称的路径,那么到目前为止这些函数都没有检查目录名称的大小写。