Java io が文字化けした場合はどうすればよいですか? Java における IO と中国語の文字化け問題
この種のブログを投稿するのは初めてなので、どのように始めればよいか四苦八苦しています。早速、本題に入り、要約の一部を記録しましょう。経験。簡単なものから始めましょう。私は学び始めたばかりですが、ゆっくりと学習を続けて、将来的にはより良い、より有意義なコンテンツを書くことができればと思っています。
実は職場で中国語の文字化けに遭遇することが少ないのは、会社が開発の都合上ファイルのエンコードを統一しているからです。しかし、その原理については少し理解する必要があると思います。
推奨: "java learning"
IO は入力および出力ストリームです。オブジェクト指向の理解を使用する場合、それは入力です。および出力ストリームオブジェクト 主にファイルオブジェクトの操作に使用されます。それでは、ファイル、つまり File オブジェクトの概念について少し説明しましょう。 Java では、File は日常生活で参照する特定のファイルではなく、パス オブジェクトです。たとえば、 File file=new File("D:\\aaa"); これは File オブジェクトであり、おそらくそれを表しています。はフォルダーです。おそらくパスは存在しませんが、このコードは確かにパスを表す File オブジェクトを作成します。この書き方はあまり一般的ではありません。通常、ファイル f=new File("aaa.txt");
のように、テキストや画像などを操作することが多いため、IO とファイルについては上記で簡単に説明しました。これらの写真、テキスト、ビデオ、その他の情報がストレージ デバイスにどのように保存されるかについて話します。
私の個人的な理解では、ファイルの種類に関係なく、バイナリ形式で保存され、最小単位は 8 ビットの 01 で構成される 1 バイトです。したがって、ファイルをコピーしたい場合は、バイト ストリームを操作するだけで済みます。つまり、ファイル内のすべてのバイトを取得して、別のファイルに書き込むことです。実際、理論的には可能ですが、このタイプの文字ファイルの場合は、むしろ特別です。
これが、中国語の文字化けの問題が発生する理由です。 ASCII コード テーブルは誰もがよく知っている、または少なくとも聞いたことがあるものです。これは非常に初期に登場したコード テーブルと見なされるべきです。最初は 26 個の英字といくつかの特殊記号を表すためにのみ使用されていました (コンピュータは 26 文字しか認識しないため)バイナリなので、コード テーブルを形成するには文字を対応するバイトに置き換える必要があります)。
しかし、コンピューターの発展に伴い、ASCII だけでは不十分になる可能性があり、多くの国が独自のエンコード スキームを持っているため、さまざまなエンコード テーブルが登場しています。一般的なものは GBK と UTF-8 で、jvm で使用されるデフォルトのエンコードは Unicode エンコード、つまり 2 バイトで中国語の文字を表しますが、UTF-8 は必ずしも当てはまりません。中国語の文字を表すのに 3 バイトの場合もあります。 、 以上。そこで問題となるのが、同じ漢字でもコード表が異なれば、対応するバイトコードの数や内容が異なるということです。
それでは、どうやって解決すればいいのでしょうか?
画像をディスク A からディスク B にコピーする場合、必要なのは A のすべてのバイトを B に取得することだけです。しかし、実際には、A と B のテキスト エンコーディングが同じでなければならないという条件で、同じ方法でテキストを操作することが可能です。なぜなら、画像にはバイトエンコーディングの問題がないからです。しかし、ネットワークまたはサーバーから中国語を送信したい場合はどうすればよいでしょうか? それは確かにバイトだけでは実現できません (問題が発生した場合にファイルのエンコードを手動で変更できないため)。そこでJavaでは、文字化けの問題を解決するために、バイトストリームに基づいてエンコード設定を追加する文字ストリームオブジェクトを提供しています。
さっそく、いくつかの小さなケースを使って説明しましょう:
1. まず、現在のプロジェクトの下に aa.txt と bb.txt を作成します。 aa にいくつかの漢字を書くだけです。文字ストリーム
FileReader fr=new FileReader("aa.txt"); FileWriter fw=new FileWriter("bb.txt"); int c; while((c=fr.read())!=-1){ fw.write(c); } fr.close(); fw.close();
b を使用する方法とバイト ストリーム
FileInputStream fis=new FileInputStream("aa.txt"); FileOutputStream fos=new FileOutputStream("bb.txt"); int b; while((b=fis.read())!=-1){ fos.write(b); } fis.close(); fos.close();
2 を使用する方法の両方で
a を達成できることがわかります。 aa のメソッドが UTF-8 の場合、bb のエンコードを GBK に変更して、上記 2 つのメソッドを再度実行すると、すべて文字化けします。
理由は、2 つのファイルのエンコード方法が異なるため、中国語のコード表が異なるため、コードが文字化けするためです。
3 したがって、2 つのファイルのエンコード方式が異なる場合、読み取りおよび書き込み時にファイルに対応するエンコードを指定できます。
InputStreamReader isr=new InputStreamReader(new FileInputStream("aa.txt"),"utf-8"); OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("bb.txt"),"gbk"); char[] arr=new char[1024]; int len; while((len=isr.read(arr))!=-1){ String s=new String(arr,0,len); System.out.println(s); osw.write(s); } isr.close(); osw.close();
コードは非常にシンプルですが、簡単に説明すると、API を見ると、InputStreamReader と OutputStreamWriter はどちらも文字を操作するオブジェクトであることがわかります。リーダーとライターを続けます。
は主に、バイトを文字に変換し、文字をバイトに変換するために使用されます。したがって、渡されるものがバイト ストリーム オブジェクトであることも構造からわかります。 UTF-8 を使用してバイト ストリームを読み取り、それを文字に変換し、その文字を gbk エンコードに変換してバイトに書き込みます。
次の行はすべて基本的なメソッドなので説明しません。構築時に渡されるのは匿名の内部クラスオブジェクトと装飾的なデザインパターンであり、この書き方だけでも理解できます。
実際には、BufferedInputStream、BufferedReader など、バイト ストリームや文字ストリームに役立つクラスが多数ありますが、これについては改めて説明しません。
jvm とシステム プラットフォームのコーディングの問題については、ここでは説明しません。
文字列で試してみて、コンパイル時と実行時に文字列のバイトコードとエンコードの問題を観察できます。
以上がJava ioが文字化けした場合の対処法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。