2010-09-30 8 views
4

Si vous essayez d'ouvrir un fichier, il indique qu'il est introuvable en raison d'une incompatibilité de jeu de caractères lorsque les noms de fichiers ont des accents. Je travaille en utilisant UTF-8 sur un système Linux (/ etc/locales définit UTF-8 aussi). Exécution jboss avec -Dfile.encoding = UTF-8 et JBOSS_ENCODING variable d'environnement = "UTF-8"Problème de charset de nom de fichier dans java

Avec JSP Je reçois le nom du fichier:

String fileName = element.getChildText("FileName"); 
out.println("File to be opened : " + filename); 

Affiche:

Fichier à ouvrir: aaaaaà.txt

Mais, un nouveau fichier (nomfichier) ne fonctionnera pas. Juste fichier.exists() est faux.

Essayer de:

File[] files = dir.listFiles(); 
for (int i=0; i<files.length; i++){ 
     out.println(fileName); 

Je reçois: Aaaaaa .txt

Pourquoi est-il en train de lire et d'essayer d'ouvrir la prise de fichier du fichier sur le disque dur ISO-8859-1? Est-ce une config JBoss? Une config java? Comment puis-je forcer java.io.File à lire le fichier en utilisant l'UTF-8 comme charset du nom de fichier?

J'ai utilisé d'autres outils et le nom est toujours lu correctement, en utilisant UTF-8.

(notez que je parle toujours sur le nom du fichier, jamais le contenu, il pourrait être un fichier vide)

+0

'-Dfile.encoding = UTF-8' est spécifique à la JVM Sun/Oracle. Quelles JVM utilisez-vous? Même alors, vous devriez après tout ne pas utiliser cet argument du tout. – BalusC

+0

@BalusC: Je ne suis pas sûr de ce que vous entendez par là. La balise "-Dfile.encoding" est également prise en charge par IBM JVM au moins (je ne suis pas sûr combien d'autres JVM sont sérieusement utilisées aujourd'hui). –

+0

JVM est Java Hotspot, de toute façon, donc il correspond au commentaire –

Répondre

3

Je suis en train de traquer le problème. Voici ce que je l'ai déjà:

Il est Exists.java:

import java.io.*; 

public class Exists { 
    public static void main(String[] args) { 
    new File("aaa").exists(); 
    new File("aaa\u00E4").exists(); 
    new File("aaa\u00C3\u00A4").exists(); 
    } 
} 

Et il est java -version:

java version "1.6.0_20" 
Java(TM) SE Runtime Environment (build 1.6.0_20-b02) 
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode) 

Passons maintenant à la partie intéressante:

$ strace -f -o strace.out java Exists && grep 'stat("aaa' strace.out 
31942 stat("aaa", 0x41464950)   = -1 ENOENT (No such file or directory) 
31942 stat("aaa\303\244", 0x41464950) = -1 ENOENT (No such file or directory) 
31942 stat("aaa\303\203\302\244", 0x41464950) = -1 ENOENT (No such file or directory) 

La bonne chose est que strace fonctionne sur le niveau octet, pas de charact niveau er comme Java. Donc tout va bien dans ce cas. J'ai la variable d'environnement LANG définie à en_US.UTF-8, toutes les variables LC_* sont désactivées.

suivi maintenant sur le problème à un exemple de travail minimal:

$ strace -f -o strace.out env - LC_ALL=en_US.UTF-8 /home/roland/bin/java Exists && grep 'stat("aaa' strace.out 
31968 stat("aaa", 0x41a75950)   = -1 ENOENT (No such file or directory) 
31968 stat("aaa\303\244", 0x41a75950) = -1 ENOENT (No such file or directory) 
31968 stat("aaa\303\203\302\244", 0x41a75950) = -1 ENOENT (No such file or directory) 

qui fonctionne encore. Alors essayons un autre encodage:

$ strace -f -o strace.out env - LANG=en_US.ISO-8859-1 /home/roland/bin/java Exists && grep 'stat("aaa' strace.out 
32070 stat("aaa", 0x407a3950)   = -1 ENOENT (No such file or directory) 
32070 stat("aaa?", 0x407a3950)   = -1 ENOENT (No such file or directory) 
32070 stat("aaa??", 0x407a3950)   = -1 ENOENT (No such file or directory) 

Cela ne fonctionne pas. Une raison possible pourrait être que j'ai sélectionné une locale qui ne figure pas dans la liste imprimée par locale -a. Mais cela ne devrait pas être la raison pour Java de convertir les lettres en points d'interrogation.

Dès que LANG pointe vers un environnement local inexistant, le paramètre de la propriété sun.jnu.encoding n'a plus d'effet. Donc je n'ai plus d'idées maintenant.

+0

Le point d'interrogation est censé être affiché en essayant d'encoder un ISO avec UTF-8. Il semble que vous faites le contraire, il devrait donc écrire quelque chose comme "Ã ·". Je suppose que c'est un problème de console consistant à écrire en UTF (encore) quelque chose de strace converti en ISO. –

+0

Non, ce n'est pas le cas. Pourquoi les octets UTF-8 devraient-ils être affichés comme des échappements octaux et les octets latins1 non? Comme je l'ai dit, "strace" fonctionne au niveau octet. Sinon, il serait inutile pour les données binaires. –

+0

'" aaa \ u00c3 \ u00A4 "' ne veut pas dire ce que vous pensez que cela signifie. Il représente cinq caractères, pas cinq octets. Le nom de fichier ne comporte que quatre caractères. '" aaa \ u00E4 "' est correct. –