通过 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.encoding 和 sun.jnu.encoding 属性启动程序,但没有任何改变.
我开始怀疑真相是否真的存在,所以我们将不胜感激。
您从哪里可以看到文件名中的问号?可能是您尝试在其中执行 ls -l(或其他操作)的控制台根本没有字形来适当地呈现您的奇异字符。
创建这样的文件后,尝试使用预期的名称和带问号的名称打开它。您很快就会知道名称本身在文件创建过程中是否真的搞砸了。
好吧,这似乎是旧文件 API 中的一个长期存在的错误。我已经解决了我所有的问题 - 没有任何额外的配置 - 通过切换到更新的 java.nio 包 .
我遇到了一个问题,我已经被它困扰了很长一段时间。问题是,我无法获取支持特殊字符的文件名(只有文件名,文件内容可以)。取而代之的是,文件名创建时带有问号。
现在,据我所知(我很可能遗漏了一些非常明显的东西),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.encoding 和 sun.jnu.encoding 属性启动程序,但没有任何改变.
我开始怀疑真相是否真的存在,所以我们将不胜感激。
您从哪里可以看到文件名中的问号?可能是您尝试在其中执行 ls -l(或其他操作)的控制台根本没有字形来适当地呈现您的奇异字符。
创建这样的文件后,尝试使用预期的名称和带问号的名称打开它。您很快就会知道名称本身在文件创建过程中是否真的搞砸了。
好吧,这似乎是旧文件 API 中的一个长期存在的错误。我已经解决了我所有的问题 - 没有任何额外的配置 - 通过切换到更新的 java.nio 包 .