【问题标题】:Python: getting filename case as stored in Windows?Python:获取存储在 Windows 中的文件名大小写?
【发布时间】:2010-01-21 23:30:54
【问题描述】:

虽然 Windows 不区分大小写,但它确实在文件名中保留大小写。在 Python 中,有什么方法可以获取文件名的大小写,因为它存储在文件系统中?

例如,在 Python 程序中,我有 filename = "texas.txt",但我想知道它实际上存储在文件系统上的 "TEXAS.txt",即使这对于各种文件操作来说都是无关紧要的。

【问题讨论】:

  • (意外重复账户合并)

标签: python windows case filenames


【解决方案1】:

这是最简单的方法:

>>> import win32api
>>> win32api.GetLongPathName(win32api.GetShortPathName('texas.txt')))
'TEXAS.txt'

【讨论】:

  • win32api.GetLongPathName(win32api.GetShortPathName('texas.txt')) 工作吗?
  • 是的,这行得通。实际上,澄清一下,您最初的建议确实有效,但如果包含目录则无效 - 例如,win32api.GetLongPathName('\\states\\texas.txt') 产生 '\\states\\TEXAS.txt',而 win32api.GetLongPathName(win32api.GetShortPathName('\\states\\texas.txt')) 正确产生 '\\STATES\\TEXAS.txt'。这让我很困惑,现在我已经准备好了。谢谢!
  • 我明白了。然后,我修改了我的回答,也叫win32api.GetShortPathName
  • 很好的解决方案;澄清一下:需要令人费解的内部 GetShortPathName() 调用,因为 GetLongPathName() 确实 大小写正确的路径 已经 长(非 8.3 格式)。在 Python 3.x 中,即使使用非 ASCII 文件名,该示例也可以按原样工作,但在 2.x 中,您必须显式使用 Unicode 字符串并调用GetLongPathNameW()(注意W)。如果你有pip,你可以通过运行pip install pypiwin32来安装win32api模块(通过pypiwin32包)
  • 请注意,如果文件没有短文件名(如果系统或卷上禁用了短文件名生成,则会发生这种情况),此解决方案将起作用。此外,GetLongPathName 不会更正驱动器号的大小写。
【解决方案2】:

我在上面的 win32api 解决方案中遇到了特殊字符的问题。对于您需要使用的 unicode 文件名:

win32api.GetLongPathNameW(win32api.GetShortPathName(path))

【讨论】:

  • 好点(适用于 Python 2.x - 在 3.x 上不需要,它本身是 Unicode)。明确一点:输入路径(也)必须是 Unicode 字符串(例如,u'texas.txt')。
  • 查看我对stackoverflow.com/a/2114975/179715 的评论;如果禁用短文件名生成,则不能保证有效。
【解决方案3】:

这只是标准库,转换所有路径部分(驱动器号除外):

def casedpath(path):
    r = glob.glob(re.sub(r'([^:/\\])(?=[/\\]|$)|\[', r'[\g<0>]', path))
    return r and r[0] or path

这个还处理 UNC 路径:

def casedpath_unc(path):
    unc, p = os.path.splitunc(path)
    r = glob.glob(unc + re.sub(r'([^:/\\])(?=[/\\]|$)|\[', r'[\g<0>]', p))
    return r and r[0] or path

注意:它比 文件系统相关 Win API "GetShortPathName" 方法要慢一些,但可以独立于平台和文件系统工作,也可以在切换短文件名生成时工作在 Windows 卷上关闭 (fsutil.exe 8dot3name query C:)。后者是recommended,至少对于性能关键文件系统而言,当没有 16 位应用程序不再依赖它时:

fsutil.exe behavior set disable8dot3 1

【讨论】:

  • 还需要保护copy[12]等路径中的方括号。如果您不介意,我将使用glob.escape 来扩充答案
  • @robyschek 是的,但是我将保护直接嵌入到 sub 中,因此它还支持结束 [ (如 oddfilename[oddfilename] )和 Py 2.7 &
【解决方案4】:
>>> import os
>>> os.listdir("./")
['FiLeNaMe.txt']

这能回答你的问题吗?

【讨论】:

    【解决方案5】:

    如果你想递归目录

    import os
    path=os.path.join("c:\\","path")
    for r,d,f in os.walk(path):
        for file in f:
            if file.lower() == "texas.txt":
                  print "Found: ",os.path.join( r , file )
    

    【讨论】:

      【解决方案6】:

      你可以使用:

      import os
      a = os.listdir('mydirpath')
      b = [f.lower() for f in a]
      try:
          i = b.index('texas.txt')
          print a[i]
      except ValueError:
          print('File not found in this directory')
      

      这当然假设您的搜索字符串'texas.txt' 是小写的。如果不是,则必须先将其转换为小写。

      【讨论】:

      • print ([f for f in os.listdir("mydirpath") if f.lower() == "texas.txt"]+["file not found"])[0]
      • @Roger:哈哈,好东西!我仍在掌握列表推导的力量。不过,我倾向于不发布单行答案,因为它们通常比启发性更令人困惑:)。
      • 请注意:不再需要使用 string.lower()。
      • except 块在功能上什么都不做——因此默默地忽略错误。
      • @Chinmay:仔细查看 except 块中的语句(即程序的最后一行)。它什么都不做
      猜你喜欢
      • 2016-11-15
      • 2011-11-05
      • 2023-03-29
      • 2012-02-03
      • 2019-06-16
      • 2016-06-22
      • 2020-10-17
      • 2013-01-12
      • 2014-03-31
      相关资源
      最近更新 更多