Java File.listFiles() 根据 'not exist'返回做 `exists()`的文件

标签 java file encoding

我在我们的生产代码中注意到了这个问题:

java.lang.IllegalArgumentException: /somePath/�.png does not exist
    at org.apache.commons.io.FileUtils.sizeOf(FileUtils.java:2413)
    at org.apache.commons.io.FileUtils.sizeOfDirectory(FileUtils.java:2479)

根本原因是这样的:

import java.io.File;

public class FileNameTest
{

    public static void main(String[] args)
    {
        File[] files = new File("/somePath").listFiles();
        for (File file : files)
        {
            System.out.println(file + " - " + (file.exists() ? "exists" : "missing!!"));
        }
    }

}

输出:

0.png - exists
7.png - exists
4.png - exists
8.png - exists
1.png - exists
3.png - exists
�.png - missing!!
2.png - exists
5.png - exists
�.png - missing!!
6.png - exists
d.png - exists
$.png - exists
s.png - exists
+.png - exists
9.png - exists

“丢失”的文件用符号 "µ" (Mu) 命名和 "€" (Euro) .

这些文件名似乎也使用了错误的编码。 当我在 bash 中列出文件时,它们也显示错误。 当我将 ls 的输出从 latin1 转换为 UTF-8 时,它们显示正确(至少 mu)。

不过……

  1. 这些文件存在
  2. file.listFiles() 列出它们
  3. 对于 2 个特殊情况:file.exists() 返回 false

我认为这是 JVM 中的错误。谁能证实这一点?

是否已经有错误报告?任何想法如何解决这一问题? (重命名文件不是一种选择,因为它们是用户生成的并且可能会以任何形式或形状重新出现。)

我的系统:

  • Ubuntu 4.2.0
  • Java 版本“1.8.0_102”
  • Java(TM) SE 运行时环境(build 1.8.0_102-b14)
  • Java HotSpot(TM) 64 位服务器虚拟机(build 25.102-b14,混合模式)
  • Apache Commons IO 2.4

最佳答案

这不是错误,而是文件系统中缺少编码信息的结果。 Java 无法正确表示文件名,因为它不知道编码。因此,如果不指定正确的编码,则无法从 Java 访问该文件。

解决此问题的最简单方法是正确设置 file.encoding 属性,并在所有文件名中使用该编码。

编辑: 我发现一篇文章显示了另一种可能的行为,也许更改 file.encoding 没有帮助。如果你想使用 UTF-8 以外的东西,最好测试一下。 http://jonisalonen.com/2012/java-and-file-names-with-invalid-characters/

我还发现了一个相关的讨论:Setting file name encoding

关于Java File.listFiles() 根据 'not exist'返回做 `exists()`的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40048757/

相关文章:

java - Heroku 进程应该始终保持运行状态,但是当它被 ping 到时,它会崩溃并出现 H20 错误

java - 如何在 reader.readLine() 期间检测第一行和最后一行?

无法从打开的文件中读取

php - 即使尽可能设置 UTF-8,也无法显示德语变音符号

java - 我是否应该子类化 JFrame/JPanel?

java - 将字符串从 XML 转换为 Java 代码

java - 当类实现 Serialized 时出现 NotSerializedException

java - 如何在 Java 中以原子方式将一个目录替换为另一个目录?

python - 使用正确的字符编码进行抓取(python 请求 + beautifulsoup)

c# - 获取.MP4文件中的音频和视频流计数及其属性