Javaでテキストファイルに書き込む方法は複数あります。ポイントは文字コードの指定と上書き/追記の使い分けです。文字コードを指定しないと日本語が文字化けし、うっかりすると既存ファイルを上書きして消してしまいます。この記事で安全な書き込み方を解説します。
この記事の結論:行を書くなら
BufferedWriter、簡潔に一括なら Files.write() / Files.writeString()。日本語ではStandardCharsets.UTF_8 を明示。デフォルトは上書きなので、追記したいときは append=true やStandardOpenOption.APPEND を指定します。最重要:文字コードを指定しないと文字化けする
FileWriter や new PrintWriter(ファイル名) はプラットフォーム既定の文字コードで書き込みます。Windows(既定がMS932/Shift-JIS系)でUTF-8として書きたい場合、明示しないと文字化けします。
読み込み側がUTF-8を期待しているのに既定の文字コードで書くと、日本語が文字化けします。書き込みでも
StandardCharsets.UTF_8 を明示しましょう。読み込み側の注意はファイルを読み込む方法も参照してください。BufferedWriterで書き込む(UTF-8明示)
行単位で効率よく書き込む定番です。文字コードを指定するためOutputStreamWriter を挟みます(Java 11以降は new FileWriter(file, UTF_8) も可)。
BufferedWriter(UTF-8)
import java.io.*;
import java.nio.charset.StandardCharsets;
public class Main {
public static void main(String[] args) {
try (BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("example.txt"), StandardCharsets.UTF_8))) {
bw.write("こんにちは");
bw.newLine(); // 改行
bw.write("世界");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Filesクラスで一括書き込み(Java 7+)
もっとも簡潔な方法です。Files.write() は行のリストを、Files.writeString()(Java 11+)は1つの文字列を書き込みます。文字コードも指定できます。
Files.write / writeString
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.List;
public class Main {
public static void main(String[] args) throws IOException {
Path path = Paths.get("example.txt");
// 行のリストを書き込む(charset明示)
Files.write(path, List.of("1行目", "2行目"), StandardCharsets.UTF_8);
// 文字列を一括で書き込む(Java 11+)
Files.writeString(path, "こんにちは世界", StandardCharsets.UTF_8);
}
}
上書きと追記の切り替え
これらの方法はデフォルトで上書き(既存内容を消す)です。末尾に追記したい場合は、追記モードを指定します。
追記する
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
public class Main {
public static void main(String[] args) throws IOException {
// FileWriter は第2引数 true で追記(Java 11+はcharsetも指定可)
try (BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("log.txt", true), StandardCharsets.UTF_8))) {
bw.write("追記行");
bw.newLine();
}
// Files は StandardOpenOption.APPEND で追記
Files.writeString(Paths.get("log.txt"), "追記\n",
StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.APPEND);
}
}
追記のつもりが上書きになっていないか注意してください。
FileOutputStream(file) や Files.write() は既定で上書きです。追記は FileOutputStream(file, true)(第2引数true)やStandardOpenOption.APPEND を明示します。PrintWriter:整形して書き込む
PrintWriter は println や printf で整形しながら書けます。こちらも文字コードを指定しましょう。
PrintWriter(UTF-8)
import java.io.*;
import java.nio.charset.StandardCharsets;
public class Main {
public static void main(String[] args) throws IOException {
try (PrintWriter pw = new PrintWriter(
new OutputStreamWriter(
new FileOutputStream("example.txt"), StandardCharsets.UTF_8))) {
pw.println("名前: 太郎");
pw.printf("得点: %d点%n", 95);
}
}
}
よくある質問(FAQ)
Q書き込んだ日本語が文字化けします。
AFileWriterやPrintWriter(ファイル名)は既定の文字コードで書くためです。
OutputStreamWriter で StandardCharsets.UTF_8 を明示するか、Files.writeString(path, text, StandardCharsets.UTF_8) を使ってください。Qファイルが上書きされて前の内容が消えました。
Aこれらの書き込みはデフォルトで上書きだからです。末尾に追記したい場合は
FileOutputStream(file, true)(第2引数true)やStandardOpenOption.APPEND を指定してください。Q一番簡潔に書き込む方法は?
AJava 11以降なら
Files.writeString(path, text, StandardCharsets.UTF_8) が最も簡潔です。行のリストなら Files.write(path, lines, charset) を使います。QnewLineとprintlnの違いは?
A
BufferedWriter.newLine() はOS依存の改行を出力します。PrintWriter.println() も改行を付けて出力します。改行コードを固定したい場合は \n を直接書く方法もあります。まとめ
Javaのファイル書き込みのポイントを整理します。
- 行単位は
BufferedWriter、一括はFiles.write/writeString - 文字コードは
StandardCharsets.UTF_8を明示(FileWriterは化ける) - デフォルトは上書き。追記は
append=true/StandardOpenOption.APPEND - 整形出力は
PrintWriter(printf) - リソースは try-with-resources で確実に閉じる
関連として、ファイルを読み込む方法・CSVファイルを読み込む方法・catchブロック・例外処理もあわせて読むと、JavaのファイルI/Oに強くなれます。
