2016-11-16 19 views
0

私はcsvファイルからデータを読み取るコードを作成しました。しかし、私は£のような特殊文字は扱えません。Java - BufferedReaderで特殊文字を正しく読み取れない

たとえば、My Base Cost (K£)は、My Base Cost (K£)と読み込まれています。

これを修正するにはどうすればよいですか?

public void parseCSVFile(String filename){ 

    try { 
      br = new BufferedReader(new FileReader(csvDirectory + filename)); 

      while ((parsedLines = br.readLine()) != null) { 

       String[] parsedData = parsedLines.split(csvSplitByComma); 

       entireFeed.add(parsedData[0]); 
       entireFeed.add(parsedData[1]); 

       System.out.println(parsedData[0]); 
       System.out.println(parsedData[1]); 

       it = entireFeed.iterator(); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
} 
+2

可能な複製http://stackoverflow.com/questions/9281629/read-special-characters-in-java-with-bufferedreader –

+0

@NiranjanKumar私は以下を試みたが、それでも動作しませんでした。 BufferedReader br = new BufferedReader( 新しいInputStreamReader(新しいFileInputStream(ファイル)、 "ISO-8859-1")); – NSC

+0

[特殊文字を含む.txtファイルを読み書きする](@stackoverflow.com/questions/4597749/read-write-txt-file-with-special-characters) –

答えて

2

コードを解決する必要があります。 は、UTF-8でトリプルコードを記述したテキストです。

UTF-8では、ASCII文字(コードポイント0-127)は1バイトとして表されます。エンコーディングは必要ありません。そのため、影響を受けるのは£なのです。

£では、UTF-8で2バイト必要です。これらのバイトは、0xc2、0xa3です。 CSVファイルを作成したコードがUTF-8を正しく使用していた場合、文字はファイル内の2バイトとして表示されます。

しかし、明らかに、あるコードでは、(ISO-8859-1のような)1バイトの文字セットを使用してファイルを読み取り、個々のバイトがそれぞれの文字のように扱われるようになっています。その後、UTF-8を使用して個々の文字をエンコードしました。つまり、{0xc2、0xa3}バイトを取り、をそれぞれUTF-8でにエンコードしました。その結果、次のバイトが生成されました:0xc3、0x82、0xc2、0xa3。 (具体的には、U + 00C2文字はUTF-8で0xc3 0x82で表され、U + 00A3文字はUTF-8で0xc2 0xa3として表されます)。

その後、いつか同じことが行われました再度これらの4バイトは1バイトの文字セットを使用して読み取られ、各バイトは独自の文字として扱われ、それぞれの4文字はUTF-8でエンコードされ、0xc3,0x83,0xc2,0x82,0xc3 、0x82、0xc2、0xa3。 (すべての文字がUTF-8としてエンコードされたときに2バイトに変換されるわけではなく、これらの文字はすべて存在します)

これは、ISO-8859-1文字セットを使用してファイルを読むとき、 (技術的には、「は、単一の低9引用符」は、実際にU + 201Aであるが、多くの1バイトあたりの文字、Windowsのフォントは歴史的位置にその文字を持っていた

à ƒ  ‚ à ‚  £ 
c3 83 c2 82 c3 82 c2 a3 

:各バイトに対して1つの文字を取得します0x82)

あなたのファイルがどのようにそのようになったのか分かったので、あなたはそれについて何をしていますか?

まず、悪化させてください。ファイルを書き込んでいるコードを制御できる場合は、コードが読み取りと書き込みの両方の文字セットを明示的に指定していることを確認してください。 UTF-8は、ほとんどの場合、主に西洋の文字を使用するすべてのファイルに対して、ほとんどの場合最良の選択です。

第2に、ファイルをどのように修正しますか?この誤ったエンコーディングを自動的に検出する方法はありませんが、少なくともこの1つのファイルの場合、トリプルデコードできます。

ファイルが非常に大きくない場合は、あなただけのメモリにすべてを読むことができますが:

byte[] bytes = Files.readAllBytes(Paths.get(csvDirectory, filename)); 
// First decoding: £ is represented as four characters 
String content = new String(bytes, "UTF-8"); 

bytes = new byte[content.length()]; 
for (int i = content.length() - 1; i >= 0; i--) { 
    bytes[i] = (byte) content.charAt(i); 
} 
// Second decoding: £ is represented as two characters 
content = new String(bytes, "UTF-8"); 

bytes = new byte[content.length()]; 
for (int i = content.length() - 1; i >= 0; i--) { 
    bytes[i] = (byte) content.charAt(i); 
} 
// Third decoding: £ is represented as one character 
content = new String(bytes, "UTF-8"); 

br = new BufferedReader(new StringReader(content)); 

// ... 

それは大きなファイルの場合は、バイトとして各ラインを読みたくなります

try (InputStream in = new BufferedInputStream(
    Files.newInputStream(Paths.get(csvDirectory, filename)))) { 

    ByteBuffer lineBuffer = ByteBuffer.allocate(64 * 1024); 

    int b = 0; 
    while (b >= 0) { 
     lineBuffer.clear(); 

     for (b = in.read(); 
      b >= 0 && b != '\n' && b != '\r'; 
      b = in.read()) { 

      lineBuffer.put((byte) b); 
     } 

     if (b == '\r') { 
      in.mark(1); 
      if (in.read() != '\n') { 
       in.reset(); 
      } 
     } 

     lineBuffer.flip(); 
     byte[] bytes = new byte[lineBuffer.limit()]; 
     lineBuffer.get(bytes); 

     // First decoding: £ is represented as four characters 
     String parsedLine = new String(bytes, "UTF-8"); 

     bytes = new byte[parsedLine.length()]; 
     for (int i = parsedLine.length() - 1; i >= 0; i--) { 
      bytes[i] = (byte) parsedLine.charAt(i); 
     } 
     // Second decoding: £ is represented as two characters 
     parsedLine = new String(bytes, "UTF-8"); 

     bytes = new byte[parsedLine.length()]; 
     for (int i = parsedLine.length() - 1; i >= 0; i--) { 
      bytes[i] = (byte) parsedLine.charAt(i); 
     } 
     // Third decoding: £ is represented as one character 
     parsedLine = new String(bytes, "UTF-8"); 

     // ... 
    } 
} 
+0

説明のためにありがとう、それは私が間違って行っていたとして意味があります。私は自分のコードを修正し、現在は期待どおりに動作しています。 – NSC

2

エンコードの問題のようです。あなたのファイルがエンコードされていることを確認してください。エンコーディングがUTF-8であることをあなたがこの

new BufferedReader(new InputStreamReader(new FileInputStream("my/path/to/File"), "UTF-8")); 

ような何かを行うことができます仮定これはあなたの問題あなたのCSVが壊れて書いた

関連する問題