web-dev-qa-db-ja.com

FileWriter(Java)を使用してUTF-8でファイルを作成しますか?

私は次のコードを持っていますが、外国文字を処理するためにUTF-8ファイルとして書きたいです。これを行う方法はありますか、パラメータが必要ですか?

これにご協力いただきありがとうございます。ありがとう。

try {
  BufferedReader reader = new BufferedReader(new FileReader("C:/Users/Jess/My Documents/actresses.list"));
  writer = new BufferedWriter(new FileWriter("C:/Users/Jess/My Documents/actressesFormatted.csv"));
  while( (line = reader.readLine()) != null) {
    //If the line starts with a tab then we just want to add a movie
    //using the current actor's name.
    if(line.length() == 0)
      continue;
    else if(line.charAt(0) == '\t') {
      readMovieLine2(0, line, surname.toString(), forename.toString());
    } //Else we've reached a new actor
    else {
      readActorName(line);
    }
  }
} catch (IOException e) {
  e.printStackTrace();
}
72
user1280970

安全なエンコードコンストラクタ

Javaを取得してエンコードエラーを適切に通知するのは難しいです。 4つの代替コンストラクターのmost verboseと、悲しいことにleast usedを使用する必要がありますInputStreamReaderおよびOutputStreamWriterのそれぞれに対して、エンコーディンググリッチに関する適切な例外を受け取ります。

ファイルI/Oの場合は、常にOutputStreamWriterInputStreamReaderの両方の2番目の引数として必ず派手なエンコーダー引数を使用するようにしてください。

  Charset.forName("UTF-8").newEncoder()

他にも手の込んだ可能性はありますが、3つの単純な可能性のいずれも例外処理には機能しません。これらは:

 OutputStreamWriter char_output = new OutputStreamWriter(
     new FileOutputStream("some_output.utf8"),
     Charset.forName("UTF-8").newEncoder() 
 );

 InputStreamReader char_input = new InputStreamReader(
     new FileInputStream("some_input.utf8"),
     Charset.forName("UTF-8").newDecoder() 
 );

で実行するのは

 $ Java -Dfile.encoding=utf8 SomeTrulyRemarkablyLongcLassNameGoeShere

問題は、文字ストリームに完全なエンコーダー引数形式を使用しないため、再びエンコードの問題を見逃すことです。

より長い例

これはファイルの代わりにプロセスを管理するより長い例です。2つの異なる入力バイトストリームと1つの出力バイトストリームをすべて完全な例外処理でUTF-8文字ストリームに昇格します

 // this runs a Perl script with UTF-8 STD{IN,OUT,ERR} streams
 Process
 slave_process = Runtime.getRuntime().exec("Perl -CS script args");

 // fetch his stdin byte stream...
 OutputStream
 __bytes_into_his_stdin  = slave_process.getOutputStream();

 // and make a character stream with exceptions on encoding errors
 OutputStreamWriter
   chars_into_his_stdin  = new OutputStreamWriter(
                             __bytes_into_his_stdin,
         /* DO NOT OMIT! */  Charset.forName("UTF-8").newEncoder()
                         );

 // fetch his stdout byte stream...
 InputStream
 __bytes_from_his_stdout = slave_process.getInputStream();

 // and make a character stream with exceptions on encoding errors
 InputStreamReader
   chars_from_his_stdout = new InputStreamReader(
                             __bytes_from_his_stdout,
         /* DO NOT OMIT! */  Charset.forName("UTF-8").newDecoder()
                         );

// fetch his stderr byte stream...
 InputStream
 __bytes_from_his_stderr = slave_process.getErrorStream();

 // and make a character stream with exceptions on encoding errors
 InputStreamReader
   chars_from_his_stderr = new InputStreamReader(
                             __bytes_from_his_stderr,
         /* DO NOT OMIT! */  Charset.forName("UTF-8").newDecoder()
                         );

これで、それぞれchars_into_his_stdinchars_from_his_stdout、およびchars_from_his_stderrと呼ばれるエンコードエラーで例外を発生させる3つの文字ストリームができました。

これは、あなたがあなたの問題に必要なものよりも少しだけ複雑です。その解決策は、この答えの前半で私が与えたものです。重要な点は、これがエンコードエラーを検出する唯一の方法であるということです。

PrintStreamsの例外を食べることから始めないでください。

70
tchrist

FileWriterFileReaderを捨てます。これらは、エンコードを指定できないため、まったく役に立ちません。代わりに、使用します

new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)

そして

new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8);

48

OutputStreamWriterクラスのライターパラメーターとしてBufferedWriterクラスを使用する必要があります。エンコードを受け入れます。 javadocs を確認してください。

ややこのような:

BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
    new FileOutputStream("jedis.txt"), "UTF-8"
));

または、システムプロパティfile.encodingで現在のシステムエンコーディングをUTF-8に設定できます。

Java -Dfile.encoding=UTF-8 com.jediacademy.Runner arg1 arg2 ...

この特定のファイルにのみ必要な場合は、実行時にSystem.setProperty(...)でシステムプロパティとして設定することもできますが、このような場合はOutputStreamWriterを好むと思います。

システムプロパティを設定することにより、FileWriterを使用し、ファイルのデフォルトエンコーディングとしてUTF-8を使用することが期待できます。この場合、読み書きするすべてのファイルに対して。

編集

  • API 19以降、文字列「UTF-8」をStandardCharsets.UTF_8に置き換えることができます

  • 下記のコメントで tchrist で示唆されているように、ファイルのエンコーディングエラーを検出する場合は、OutputStreamWriterアプローチを使用し、charsetエンコーダーを受け取るコンストラクターを使用する必要があります。

    やや好き

    CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
    encoder.onMalformedInput(CodingErrorAction.REPORT);
    encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
    BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("jedis.txt"),encoder));
    

    アクションIGNORE | REPLACE | REPORTから選択できます

また、この質問はすでに回答済みです here

43
Edwin Dalorzo

中国語のテキストでは、Charset UTF-16を使用してみましたが、幸いにも動作します。

これが役立つことを願っています!

PrintWriter out = new PrintWriter( file, "UTF-16" );
5
Phuong

Java 7以降、BufferedWriterおよびBufferedReadersの文字エンコードを処理する簡単な方法があります。 Writerのさまざまなインスタンスを作成する代わりに、Filesクラスを使用して、BufferedWriterを直接作成できます。次を呼び出すことで、文字エンコードを考慮するBufferedWriterを簡単に作成できます。

Files.newBufferedWriter(file.toPath(), StandardCharsets.UTF_8);

詳細については、JavaDocを参照してください。

3
Lars Briem

Java 11以降、次のことができます。

FileWriter fw = new FileWriter("filename.txt", Charset.forName("utf-8"));
3
mortensi