如何在Java中打开包含重音符号的文件?
(编辑以进行澄清并添加一些代码)
您好, 我们有解析来自世界各地用户的数据的要求。我们的 Linux 系统的默认区域设置为 en_US。UTF-8.但是,我们经常收到名称中带有变音符号的文件,例如“”。虽然操作系统可以很好地处理这些文件,并且一个strace显示操作系统将正确的文件名传递给Java程序,但Java会修改名称并引发“找不到文件”io异常,试图打开它们。special_á_ã_è_characters.doc
这个简单的程序可以说明这个问题:
import java.io.*;
import java.text.*;
public class load_i18n
{
public static void main( String [] args ) {
File actual = new File(".");
for( File f : actual.listFiles()){
System.out.println( f.getName() );
}
}
}
在包含该文件和默认美国英语区域设置的目录中运行此程序会得到:special_á_ã_è_characters.doc
special_ï¿1/2_ï¿1/2_ï¿1/2_characters.doc
通过导出 LANG=es_ES@UTF-8 设置语言可以正确打印出文件名(但这是一个不可接受的解决方案,因为整个系统现在都以西班牙语运行。像下面这样在程序中显式设置区域设置也没有效果。下面我将程序修改为a)尝试打开文件,b)在无法打开文件时以ASCII和字节数组的形式打印出名称:
import java.io.*;
import java.util.Locale;
import java.text.*;
public class load_i18n
{
public static void main( String [] args ) {
// Stream to read file
FileInputStream fin;
Locale locale = new Locale("es", "ES");
Locale.setDefault(locale);
File actual = new File(".");
System.out.println(Locale.getDefault());
for( File f : actual.listFiles()){
try {
fin = new FileInputStream (f.getName());
}
catch (IOException e){
System.err.println ("Can't open the file " + f.getName() + ". Printing as byte array.");
byte[] textArray = f.getName().getBytes();
for(byte b: textArray){
System.err.print(b + " ");
}
System.err.println();
System.exit(-1);
}
System.out.println( f.getName() );
}
}
}
这将生成输出
es_ES
load_i18n.class
Can't open the file special_�_�_�_characters.doc. Printing as byte array.
115 112 101 99 105 97 108 95 -17 -65 -67 95 -17 -65 -67 95 -17 -65 -67 95 99 104 97 114 97 99 116 101 114 115 46 100 111 99
这表明问题不仅仅是控制台显示为相同字符的问题,并且它们的表示形式以字节或ASCII格式输出。事实上,即使使用 LANG=en_US,控制台显示也确实有效。UTF-8 用于某些实用程序,如 bash 的 echo:
[mjuric@arrhchadm30 tmp]$ echo $LANG
en_US.UTF-8
[mjuric@arrhchadm30 tmp]$ echo *
load_i18n.class special_á_ã_è_characters.doc
[mjuric@arrhchadm30 tmp]$ ls
load_i18n.class special_?_?_?_characters.doc
[mjuric@arrhchadm30 tmp]$
是否可以修改此代码,以便在使用LANG=en_US的Linux下运行时。UTF-8,它以可以成功打开的方式读取文件名?