【问题标题】:How to avoid FileNotFound exception when running Java on Linux because of case sensitiveness?由于区分大小写,在 Linux 上运行 Java 时如何避免 FileNotFound 异常?
【发布时间】:2009-11-14 09:14:05
【问题描述】:

我的 Web 应用程序在 Windows 上运行。我也想在 Linux 上运行我的应用程序。路径分隔符之类的大部分问题我好像都克服了。

现在真正的问题是当 Java 代码尝试打开一个文件时我得到 FileNotFoundExceptionAbc.txt 而只有 abc.txt 存在。 :(

我无法继续将所有文件名更改为小写或大写,因为我有很多文件。在不更改代码的情况下,是否有任何可能的方法来避免这种情况?

【问题讨论】:

  • 请注意,不区分大小写的操作系统是例外而不是规则。 Windows 几乎是剩下的唯一一个以不区分大小写的方式处理文件的主要操作系统。
  • 在我看来,Windows 上的一个好策略是保持大小写,即使不区分大小写。不要让您的代码通过多个大写字母引用文件,并且不要改变给定路径的大小写。

标签: java linux case-sensitive filenotfoundexception


【解决方案1】:

修复它!

从长远来看,您为规避修复而设计的任何方案都会变得更糟。

【讨论】:

    【解决方案2】:

    没有办法避免这种情况,因为java.io.File API 依赖于系统。在 Linux/Unix 上操作文件时必须使用正确的大小写。实际上,我的建议/解决方案是在 Windows 上的开发过程中遵循严格且可移植的约定(例如,仅使用小写文件名,或者更好的是,在以编程方式访问文件时使用确切的文件名)。老实说,我不明白为什么当文件名是abc.txt 时你要加载Abc.txt。这是一个坏习惯(通过在 Windows 上花费太多时间养成的)而不是 Linux/Unix 问题。

    【讨论】:

    • 只是说这不是我的代码,但我有责任让应用程序在 linux 上运行。
    • 在所有目标平台上都有一个构建和测试服务器会在这个过程的早期发现许多这些问题。
    【解决方案3】:

    嗯,首先我认为您应该考虑改用一致的命名方案,而不是使用一些变通方法。

    无论如何,读取所有文件名并将它们放入包含小写名称作为键的映射怎么样?然后,您可以从地图中查找正确的文件名

    这也可以让您检测到冲突,例如同一目录中的两个文件“FileA.txt”和“FILEA.TXT”具有相同的小写表示,在这种情况下,您知道您必须以完全不同的方式解决问题(因为您必须知道哪个一个你想打开的,它是模棱两可的,然后这样的解决方法就不行了)。

    【讨论】:

      【解决方案4】:

      假设文件在 Linux 上是大小写混合的,对此没有简单的答案。

      我能想到的最好方法是让您的应用程序列出相关目录并创建实际 Linux 文件名的内存数据结构。然后打开不区分大小写的文件,将路径名拆分为组件,使用不区分大小写的搜索搜索内存树,构建真实(区分大小写)路径名并使用 THAT 来打开文件。

      问题在于它(实际上是您的应用程序)无法应对您在同一个 Linux 目录中有(例如)“foo.txt”和“Foo.txt”的情况。

      但最好的解决方案是更改您的应用程序,使其使用区分大小写的路径名。

      【讨论】:

        【解决方案5】:

        为什么不能更改很多文件?如果文件的数量确实是唯一让您望而却步的因素,那么只需编写一个小脚本,将它们全部重命名为小写即可。

        【讨论】:

          【解决方案6】:

          从您的问题中不清楚是什么导致您的文件大小写更改。如果您的所有文件在 linux 中都是小写,而在 Windows 上是混合大小写,您可以将文件名转换为小写,如下所示:

          new File(filename.toLowerCase())
          

          【讨论】:

            【解决方案7】:

            有一个解决方案的运行时性能很差,但实现起来却非常简单:

            用类似的东西替换new FileReader(name)

            openFile(name);
            
            public FileReader openFile(String name) throws FileNotFoundException {
              File dir = (new File(name)).getParentFile();
              for (File f : dir.listFiles()) {
                if (f.getName().equalsIgnoreCase(name)) {
                return new FileReader(f);
              }
              throw new FileNotFoundException("File not found: " + name);
            }
            

            我没有编译这段代码,它可能有错别字和错误。我把它们留给你来解决。

            【讨论】:

            • 很想这样做。 :P 但不建议对吗?将遵循最佳编程实践。 :)
            • 我们说的是打开文件的开销大约为 100 毫秒。如果它不经常发生,这个解决方案可以做到。如果性能是一个问题但目录不经常更改,您可以缓存目录列表。但从根本上解决问题将是最好的事情。你知道 Linux 上的“重命名”工具吗?
            • 这仅适用于文件名本身拼写错误的情况,而不是任何父目录中存在问题的情况。
            • 好点!当然,我的 kludge 可以扩展为对目录名做同样的事情。
            猜你喜欢
            • 1970-01-01
            • 2021-10-24
            • 2012-07-02
            • 2012-08-22
            • 1970-01-01
            • 2017-05-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多