2016-09-01 9 views
3

私はこれに対する答えを探しました(彼らがそこにいると確信しています)。Javaのあるエンコーディングから別のエンコーディングへの文字列の解釈

したがって、「för」という単語が含まれた巨大なファイルがあります。私はRandomAccessFileを使用しています。なぜなら、どこにあるのか知っていて、そこに到達するためにseek()関数を使用できるからです。

私はそれを見つけたことを知るために、私のプログラムに文字列 "för"があり、それが平等であることを確認します。ここで問題は、私はデバッガを実行し、私が "för"に到達するときに私が比較するものは "för"です。

私のプログラムは "för"を見つけることなく終了します。

これは私が単語を取得するために使用したコードです:

private static String getWord(RandomAccessFile file) throws IOException { 
    StringBuilder stb = new StringBuilder(); 
    String word; 
    char c; 
    c = (char)file.read(); 
    int end; 
    do { 
     stb.append(c); 
     end = file.read(); 
     if(end==-1) 
      return "-1"; 
     c = (char)end; 

    } while (c != ' '); 
    word = stb.toString(); 
    word.trim(); 
    return word; 
} 

だから基本的に私が最初に '「-characterにファイル内の現在の位置からすべての文字を返します。だから基本的に私は言葉を得るが、以来(char)file.read();バイト(私は思う)を読み、UTF-8 'ö'は2つの文字 'Ã'と '¶'になりますか?

私がUTF-8エンコーディングでファイルを開くと、それは "för"ですが、ISO-8859-15のファイルを同じ場所に開くと、getWordメソッドが返すもの:「för」

は、だから私の質問:私は、「FOR」と「för」で座っているとき

、この問題を解決する方法はありますか? "för"を取得するために "read"fÃr "をUTF-8文字列のように"言っているのと同じですか?

+1

あなたの問題はここです: '(char)file.read()'。 ['read()'](https://docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html#read--)メソッドは 'char'を返しません。 'byte'を返します。 'byte'を' char'にキャストしないでください。 ---なぜあなたは 'RandomAccessFile'を使用していますが、より有用な' FileReader'ではなく、自動的にバイトを文字に変換しますか? – Andreas

+0

@Andreas RandomAccessFileには、seek(long pos)という関数があり、ファイルのX個のバイトを前に開いたり読んだりすることなくジャンプさせることができます。 – MrJalapeno

+1

しかし、シークはUTF-8シーケンスの途中に上陸するかもしれないので、どこにシークするのかはどうやって決めるのですか? UTF-8では、文字は可変バイト数を占有するため、スキップするバイト数は読み取ることができません。 – Andreas

答えて

-2
import java.nio.charset.Charset; 
String encodedString = new String(originalString.getBytes("ISO-8859-15"), Charset.forName("UTF-8")); 
+0

いくつかのグーグル(わずか数秒前)の後、私は解決策のように見えるものを実装することができました。基本的には** byte [] utf8Bytes = theWord.getBytes( "ISO-8859-1"); **そしてtheWord = new String(utf8Bytes、 "UTF8"); **です。 theWordは "för"から "för"になりました。このように、あるいはそのようにする理由はありますか?ちょっと好奇心:PS私はちょうどあなたのソリューションを実装し、それも問題を解決するので、私はあなたの答えを受け入れるよ – MrJalapeno

+0

私とあなたのソリューションは同じです。唯一の違いは、私の解決策が1行であることです。 –

+1

ISO-8859-15は、コード中で行われた非常に悪い 'byte'から' char'キャストを逆にしません。 – Andreas

1

RandomAccessFile.read()を使用しています。これは1バイトを読み込みます。 UTF-8は、1文字に数バイトを使用することがあります。 RandomAccessFileからUTF-8を読むこと

異なる方法がここで説明されていますJava: reading strings from a random access file with buffered input

あなたは必ずしものRandomAccessFileを必要としない場合、あなたは間違いなく、代わりにバイト文字を読みに切り替える必要があります。

可能であれば、デフォルトで次の単語を検索するScanner.next()を提案します。あなたがbyte[]最初にコンテンツを読み込んでStringに完全な配列を変換する必要がありRandomAccessFileを使用する必要がある場合

+0

'Scanner'のパフォーマンスは恐ろしいものです。可能であれば避けてください。 – Andreas

+0

@Andreasあなたは 'Scanner'、_ifパフォーマンスの問題から離れているべきです。 – slartidan

3

- の線に沿って気にいら:

byte[] buffer = new byte[whatever]; 
file.read(buffer); 
String result = new String(buffer,"UTF-8"); 

これはあなたを与えることだけです一般的な印象は何をするか、長さの扱いなどを追加する必要があります。

UTF-8シーケンスの途中で読み始めると正しく動作しませんが、他の方法もそうです。

関連する問題