Lecture UTF-8 – Marqueur de nomenclature

Je lis un fichier via un FileReader – le fichier est décodé en UTF-8 (avec BOM). Pourquoi cela se produit?

fr = new FileReader(file); br = new BufferedReader(fr); Ssortingng tmp = null; while ((tmp = br.readLine()) != null) { Ssortingng text; text = new Ssortingng(tmp.getBytes(), "UTF-8"); content += text + System.getProperty("line.separator"); } 

sortie après la première ligne

 ? 

En Java, vous devez consumr manuellement la nomenclature UTF8 si elle est présente. Ce comportement est documenté dans la firebase database de bogues Java, ici et ici . Il n’y aura pas de correctif pour le moment car il va casser les outils existants comme JavaDoc ou les parsingurs XML. Apache IO Commons fournit un BOMInputStream pour gérer cette situation.

Jetez un oeil à cette solution: gérer le fichier UTF8 avec la nomenclature

La solution la plus simple est probablement de supprimer le \uFEFF résultant de la chaîne, car il est extrêmement improbable qu’il apparaisse pour une autre raison.

 tmp = tmp.replace("\uFEFF", ""); 

Voir aussi ce rapport de bogue Guava

Utilisez la bibliothèque Apache Commons .

Classe: org.apache.commons.io.input.BOMInputStream

Exemple d’utilisation:

 Ssortingng defaultEncoding = "UTF-8"; InputStream inputStream = new FileInputStream(someFileWithPossibleUtf8Bom); try { BOMInputStream bOMInputStream = new BOMInputStream(inputStream); ByteOrderMark bom = bOMInputStream.getBOM(); Ssortingng charsetName = bom == null ? defaultEncoding : bom.getCharsetName(); InputStreamReader reader = new InputStreamReader(new BufferedInputStream(bOMInputStream), charsetName); //use reader } finally { inputStream.close(); } 

Voici comment j’utilise Apache BOMInputStream, il utilise un bloc try-with-resources. L’argument “false” indique à l’object d’ignorer les nomenclatures suivantes (nous utilisons des fichiers texte “sans nomenclature” pour des raisons de sécurité, haha):

 try( BufferedReader br = new BufferedReader( new InputStreamReader( new BOMInputStream( new FileInputStream( file), false, ByteOrderMark.UTF_8, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_32BE, ByteOrderMark.UTF_32LE ) ) ) ) { // use br here } catch( Exception e) } 

Il est mentionné ici qu’il s’agit généralement d’un problème avec les fichiers sous Windows.

Une solution possible serait d’exécuter le fichier via un outil tel que dos2unix.

Utilisez Apache Commons IO .

Par exemple, voyons ci-dessous mon code (utilisé pour lire un fichier texte contenant des caractères latins et cyrilliques):

 Ssortingng defaultEncoding = "UTF-16"; InputStream inputStream = new FileInputStream(new File("/temp/1.txt")); BOMInputStream bomInputStream = new BOMInputStream(inputStream); ByteOrderMark bom = bomInputStream.getBOM(); Ssortingng charsetName = bom == null ? defaultEncoding : bom.getCharsetName(); InputStreamReader reader = new InputStreamReader(new BufferedInputStream(bomInputStream), charsetName); int data = reader.read(); while (data != -1) { char theChar = (char) data; data = reader.read(); ari.add(Character.toSsortingng(theChar)); } reader.close(); 

En conséquence, nous avons une ArrayList nommée “ari” avec tous les caractères du fichier “1.txt” à l’exception de la BOM.

Considérez UnicodeReader de Google qui fait tout ce travail pour vous.

 Charset utf8 = Charset.forName("UTF-8"); // default if no BOM present try (Reader r = new UnicodeReader(new FileInputStream(file), utf8)) { .... } 

Dépendance de Maven:

  com.google.gdata core 1.47.1  

La manière la plus simple de contourner la nomenclature

 BufferedReader br = new BufferedReader(new InputStreamReader(fis)); while ((currentLine = br.readLine()) != null) { //case of, remove the BOM of UTF-8 BOM currentLine = currentLine.replace("","");