【问题标题】:How to handle OSError: [Errno 36] File name too long如何处理 OSError:[Errno 36] 文件名太长
【发布时间】:2017-06-12 18:19:26
【问题描述】:

在处理尝试创建现有文件或尝试使用不存在的文件时发生的错误时,抛出的OSErrors 有一个子类(FileExistsErrorFileNotFoundError)。当文件名太长时,我找不到特殊情况的子类。

确切的错误信息是:

OSError: [Errno 36] File name too long: 'filename'

我想捕捉文件名过长时发生的 OSError,但仅当文件名过长时。我确实想捕捉其他可能发生的OSErrors。有没有办法做到这一点?

编辑:我知道我可以根据长度检查文件名,但最大文件名长度因操作系统和文件系统而异,而且我没有看到一个“干净”的解决方案方式。

【问题讨论】:

  • @NuclearPeon:不。那是特定于 Windows 的,那里的答案不能回答这个问题。我在问题中指定了这一点。
  • 您可以尝试获取最大文件名路径,尽管没有确定的方法可以做到这一点。检查此链接:code.activestate.com/lists/python-list/210662 - 检查文件名的长度,如果太长则通知用户。否则,try/except 是您已经列出的最佳选择。
  • 我专门询问了如何捕获确切的错误。由于竞争条件和最大文件名长度的不一致(如问题中所述),我不想事先检查长度。
  • 我见过的缩小 OSError 范围的唯一方法是在抛出异常时检查第三个参数。请参阅此处的文档:docs.python.org/2/library/exceptions.html#exceptions.OSError - 相关信息:For exceptions that involve a file system path (such as chdir() or unlink()), the exception instance will contain a third attribute, filename, which is the file name passed to the function. 您可能不得不得出这样的结论,即 Python 没有确定的方式来做您想做的事。提交错误。

标签: python python-3.x filenames long-filenames


【解决方案1】:

只需检查捕获异常的errno 属性。

try:
    do_something()
except OSError as exc:
    if exc.errno == 36:
        handle_filename_too_long()
    else:
        raise  # re-raise previously caught exception

为了便于阅读,您可以考虑使用来自errno built-in module 的适当常量,而不是硬编码常量。

【讨论】:

  • 但是我也捕捉到了我特别不想捕捉的其他OSErrors!
【解决方案2】:

您可以指定如何捕获特定错误,例如errno.ENAMETOOLONG

针对您的问题...

try:
    # try stuff
except OSError as oserr:
    if oserr.errno != errno.ENAMETOOLONG:
        # ignore
    else:
        # caught...now what?

特定于您的 cmets...

try:
    # try stuff
except Exception as err:
    # get the name attribute from the exception class
    errname = type(err).__name__
    # get the errno attribute from the exception class
    errnum = err.errno
    if (errname == 'OSError') and (errnum == errno.ENAMETOOLONG):
        # handle specific to OSError [Errno 36]
    else if (errname == 'ExceptionNameHere' and ...:
        # handle specific to blah blah blah
    .
    .
    .
    else:
        raise # if you want to re-raise; otherwise code your ignore

这将捕获由try 中的错误引起的所有异常。然后它会检查__name__ 是否匹配任何特定异常以及您要指定的任何附加条件。

您应该知道,如果遇到错误,除非您指定具体的异常,否则无法绕过 except

【讨论】:

  • 但是我也捕捉到了我特别不想捕捉的其他OSErrors!
  • @MaxMatti 要“捕捉”和错误,您必须“处理”它。 if/else 设置条件if 异常errno 属性不等于(!=),您编写代码忽略它(无论您选择这样做); else 你已经“抓住”了正确的异常......现在“处理”它。
  • 我不想忽略它!我想抓住它。我在我的问题中说:“我确实想要捕捉其他可能发生的OSErrors。有没有办法实现这一点?”如果 errno 不等于 errno.ENAMETOOLONG 有办法让先前的错误进一步传播,请将其添加到您的答案中。但目前我不知道您打算如何实现这一目标。
  • @MaxMatti 假设您有两个错误:E1 和 E2。在您的try/except 中,您只想捕获 E2,这是您当前关注的错误。您知道类型 (OSError),但这不是 except 语句的工作方式。它是一个built-in,因此您必须参考errno 模块以获取其映射的错误代码。但是,如果您遇到的第一个错误是 E1 怎么办?因为OSError 是内置的,所以在except 中没有要指定的OSError.ENAMETOOLONG。在发布的两个答案中,如果不是 E2,您可以继续前进。
  • @MaxMatti 仅仅因为您检查OSError 是否是您特别要处理的,并不会损害代码。如果遇到错误,try 语句中正在执行的任何内容都受except 的约束。没有except OSError as oserr if oserr.errno == errno.ENAMETOOLONG
猜你喜欢
  • 2015-07-05
  • 1970-01-01
  • 1970-01-01
  • 2020-04-08
  • 2019-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多