В следующей программе на Java, работающей в Linux с использованием OpenJDK 1.6.0 _22, я просто перечисляю содержимое каталога, взятого в качестве параметра в командной строке. Каталог содержит файлы с именами файлов в UTF -8 (, например. Хинди, китайский, немецкий и т. д. ).
import java.io.*;
class ListDir {
public static void main(String[] args) throws Exception {
//System.setProperty("file.encoding", "en_US.UTF-8");
System.out.println(System.getProperty("file.encoding"));
File f = new File(args[0]);
for(String c : f.list()) {
String absPath = args[0] + "" + c;
File cf = new File(args[0] + "/" + c);
System.out.println(cf.getAbsolutePath() + " --> " + cf.exists());
}
}
}
Если я установлю для переменной LC _ALL значение en _US.UTF -8, результаты будут напечатаны нормально. Но если я устанавливаю переменную LC _ALL в POSIX и передаю свойства file.encoding и sun.jnu.encoding как UTF -8 из командной строки, я получаю вывод мусора, а cf.exists ()возвращает false.
Не могли бы вы объяснить это поведение. Как я читал на многих веб-сайтах, file.encoding считается достаточным для чтения имен файлов и использования их для операций. Здесь похоже, что это свойство вообще не имеет никакого эффекта.
Обновление 1:Если я установлю для file.encoding что-то вроде GBK (китайский )и переменную LC _ALL для en _US.UTF -8, тогда cf.exists ()вернет true. только '?' появляется вместо имени файла. Сюрприз о _О.
Обновление 2:Больше исследований, и похоже, что это не проблема Java. Похоже, что libc в Linux использовала настройки локали для перевода кодировок имен файлов, и эти настройки вызовут ошибку/исключение «Файл не найден». «file.encoding» — это то, как Java интерпретирует имена файлов.
Обновление 3 Похоже, проблема в том, как Java интерпретирует имена файлов. Следующий простой код C работает в Linux независимо от кодировки файла и значения переменной среды LC _ВСЕ переменные окружения (Я рад, что это подтверждает приведенный здесь ответ:https://unix.stackexchange.com/questions/39175/understanding-unix-file-name-encoding). Но все же мне не ясно, как Java интерпретирует переменную LC _ALL.Теперь изучаем код OpenJDK для этого.
Пример кода C:
#include
#include
#include
#include
int main(int argc, char *argv[])
{
char *argdir = argv[1];
DIR *dp = opendir(argdir);
struct dirent *de;
while(de = readdir(dp)) {
char *abspath = (char *) malloc(strlen(argdir) + 1 + strlen(de->d_name) + 1);
strcpy(abspath, argdir);
abspath[strlen(argdir)] = '/';
strcpy(abspath + strlen(argdir) + 1, de->d_name);
printf("%d %s ", de->d_type, abspath);
FILE *fp = fopen(abspath, "r");
if (fp) {
printf("Success");
}
fclose(fp);
putchar('\n');
}
}