2009-03-30 4 views
108

Ich habe versucht, java.io.FileReader zu verwenden, um einige Textdateien zu lesen und sie in eine Zeichenfolge zu konvertieren, aber ich fand das Ergebnis falsch codiert und überhaupt nicht lesbar.Java FileReader Encoding-Problem

Hier ist meine Umgebung:

  • Windows 2003, OS-Codierung: CP1252

  • Java 5,0

Meine Dateien sind UTF-8 codiert oder CP1252 codiert, und einige sie (UTF-8-codierte Dateien) können chinesische (nicht lateinische) Zeichen enthalten.

Ich verwende den folgenden Code, um meine Arbeit zu tun:

private static String readFileAsString(String filePath) 
    throws java.io.IOException{ 
     StringBuffer fileData = new StringBuffer(1000); 
     FileReader reader = new FileReader(filePath); 
     //System.out.println(reader.getEncoding()); 
     BufferedReader reader = new BufferedReader(reader); 
     char[] buf = new char[1024]; 
     int numRead=0; 
     while((numRead=reader.read(buf)) != -1){ 
      String readData = String.valueOf(buf, 0, numRead); 
      fileData.append(readData); 
      buf = new char[1024]; 
     } 
     reader.close(); 
     return fileData.toString(); 
    } 

Der obige Code funktioniert nicht. Ich fand die Kodierung des FileReaders CP1252, selbst wenn der Text UTF-8 kodiert ist. Aber die JavaDoc von java.io.FileReader sagen, dass:

Die Konstrukteure dieser Klasse annehmen, dass die Standard-Zeichenkodierung und die Standard-Byte-Puffergröße ist angemessen.

Bedeutet dies, dass ich die Zeichencodierung nicht selbst einstellen muss, wenn ich FileReader verwende? Aber ich habe gerade falsch codierte Daten bekommen, was ist der richtige Weg, um mit meiner Situation umzugehen? Vielen Dank.

+0

Sie sollten auch die String.valueOf() innerhalb der Schleife verlieren und StringBuffer.append (char [], int, int) direkt verwenden. Dies erspart viel Kopieren von char []. Ersetzen Sie StringBuffer auch durch StringBuilder. Nichts davon ist jedoch deine Frage. –

+1

Ich hasse es zu sagen, aber haben Sie den JavaDoc direkt nach dem Teil gelesen, den Sie eingefügt haben?Sie wissen, der Teil, der sagt "Um diese Werte selbst zu spezifizieren, konstruiere einen InputStreamReader auf einem FileInputStream."? – Powerlord

+0

Vielen Dank für Ihren Kommentar, ich lese tatsächlich die JavaDoc, aber was ich nicht sicher bin, ist, ob ich diese Werte selbst angeben sollte, und wechseln Sie zu "Konstruieren Sie einen InputStreamReader auf einem FileInputStream". – nybon

Antwort

198

Ja, Sie müssen die Codierung der Datei angeben, die Sie lesen möchten.

Ja, das bedeutet, dass Sie wissen müssen die Codierung der Datei, die Sie lesen möchten.

Nein, es gibt keinen allgemeinen Weg zu erraten die Codierung von jeder gegebenen "Klartext" -Datei.

The constructors of FileReader verwenden Sie immer die Plattform Standard-Codierung, die in der Regel eine schlechte Idee ist.

Anstelle von FileReader müssen Sie new InputStreamReader(new FileInputStream(pathToFile) verwenden.

+1

InputStream ist = new FileInputStream (Dateiname); hier habe ich Fehler Datei nicht gefunden Fehler mit russischen Dateinamen –

+2

+1 für den Vorschlag der Verwendung von InputStreamReader, aber die Verwendung von Links in Codeblöcke macht es schwer zu kopieren und fügen Sie den Code, wenn dies geändert werden kann, thx – Ferrybig

+0

Würde es sein " UTF-8 "oder" UTF8 "in den Kodierungen. Laut [der Java SE Referenz zur Kodierung] (https://docs.oracle.com/javase/8/docs/technotes/guides/intl/encoding.doc.html), da 'InputStreamReader' ein' java.io ist 'Klasse, es wäre" UTF8 "? – NobleUplift

71

FileReader verwendet Java-Standardkodierung, die von den Systemeinstellungen des Computers abhängt, auf dem es ausgeführt wird, und ist in der Regel die beliebteste Kodierung unter den Benutzern in diesem Gebietsschema.

Wenn diese "beste Schätzung" nicht korrekt ist, müssen Sie die Codierung explizit angeben. Leider erlaubt FileReader dies nicht (Hauptversehen in der API). Stattdessen müssen Sie new InputStreamReader(new FileInputStream(filePath), encoding) verwenden und im Idealfall die Codierung von Metadaten über die Datei erhalten.

+17

"Hauptversehen in der API" - Danke für diese Erklärung - Ich habe mich gefragt, warum ich den Konstruktor, nach dem ich gesucht habe, nicht finden konnte! Prost John – monojohnny

+0

@Bhanu Sharma: das ist ein Codierungs-Problem auf einer anderen Ebene, überprüfen Sie, wo Sie den Dateinamen erhalten, und wenn es hart codiert ist, welche Codierung verwendet der Compiler. –

+0

ich benutze beide Dateinamen und hardcoded als eine Zeichenfolge, aber das gleiche Problem bekomme ich was soll ich tun :( –