file.encoding не имеет никакого эффекта, переменная окружения LC_ALL делает это
В следующей 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 считается достаточным для чтения имен файлов и использования их для операций. Здесь похоже, что это свойство не имеет никакого эффекта вообще.
Update 1: Если я устанавливаю file.encoding для чего-то вроде GBK (китайский) и переменную LC_ALL в en_US.UTF-8, тогда cf.exists () возвращает true. только "?" появляется вместо имени файла. Сюрприз о_О.
Update 2: Больше исследований, и похоже, что это не проблема Java. Похоже, что libc в Linux использовал настройки локали для перевода кодировок имен файлов, и эти настройки приведут к ошибке / исключению файла не найден. & Quot; file.encoding & Quot; для того, как Java интерпретирует имена файлов.
Update 3 Теперь выглядит проблема в том, как Java интерпретирует имена файлов. Следующий простой код C работает в Linux независимо от кодировки файла и значения переменной среды LC_ALL (я рад, что это доказывает ответ, приведенный здесь:https://unix.stackexchange.com/questions/39175/understanding-unix-file-name-encoding). Но все же мне не ясно, как Java интерпретирует переменную LC_ALL. Теперь рассмотрим код OpenJDK для этого.
Пример кода C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
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');
}
}