通过 Java 创建时 Linux 上的文件名编码问题

Problems with filename encoding on Linux when created through Java

我遇到了一个问题,我已经被它困扰了很长一段时间。问题是,我无法获取支持特殊字符的文件名(只有文件名,文件内容可以)。取而代之的是,文件名创建时带有问号。

现在,据我所知(我很可能遗漏了一些非常明显的东西),Linux 本身设置正确。 Locale 命令将打印出以下内容,我认为这很好:

    LANG=en_US.UTF-8
    LC_CTYPE="en_US.UTF-8"
    LC_NUMERIC="en_US.UTF-8"
    LC_TIME="en_US.UTF-8"
    LC_COLLATE="en_US.UTF-8"
    LC_MONETARY="en_US.UTF-8"
    LC_MESSAGES="en_US.UTF-8"
    LC_PAPER="en_US.UTF-8"
    LC_NAME="en_US.UTF-8"
    LC_ADDRESS="en_US.UTF-8"
    LC_TELEPHONE="en_US.UTF-8"
    LC_MEASUREMENT="en_US.UTF-8"
    LC_IDENTIFICATION="en_US.UTF-8"
    LC_ALL=

这是我为测试目的而编写的 Java 代码。并不是所有的东西都可以让事情变得清晰(比如 finally 块),但重要的是。我也尝试过使用 BufferedOutputStream 对主题进行变体,但结果是一样的。

    String exampleString="I'm in the file: \u0160 \u0161 \u010C \u010D";
    String filename="I'm the filename \u0160\u0161\u010C\u010D.txt";

    FileOutputStream fos = null;
    InputStream is = null;
    try {

        fos = new FileOutputStream(transferDir.getPath()
                + File.separator + "_"
                + filename);

        is = new ByteArrayInputStream(exampleString.getBytes(StandardCharsets.UTF_8));

        byte[] buffer = new byte[4096];
        int counter;
        while ((counter = is.read(buffer)) != -1) {
            fos.write(buffer, 0, counter);
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

我也试过使用 file.encodingsun.jnu.encoding 属性启动程序,但没有任何改变.

我开始怀疑真相是否真的存在,所以我们将不胜感激。

您从哪里可以看到文件名中的问号?可能是您尝试在其中执行 ls -l(或其他操作)的控制台根本没有字形来适当地呈现您的奇异字符。

创建这样的文件后,尝试使用预期的名称和带问号的名称打开它。您很快就会知道名称本身在文件创建过程中是否真的搞砸了。

好吧,这似乎是旧文件 API 中的一个长期存在的错误。我已经解决了我所有的问题 - 没有任何额外的配置 - 通过切换到更新的 java.nio 包 .