私はしばらくの間、以下の慣用句を使ってきました。そして、少なくとも私が訪れたサイトでは、これが最も広く使われているようです。
Java でファイルを文字列に読み込むためのより良い/異なる方法はありますか?
private String readFile(String file) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader (file));
String line = null;
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
try {
while((line = reader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append(ls);
}
return stringBuilder.toString();
} finally {
reader.close();
}
}
ベストアンサー1
ファイルからすべてのテキストを読み込む
Java 11では、文字列の読み取り()String
行末文字を保持しながら、小さなファイルを として読み込む方法:
String content = Files.readString(path, encoding);
Java 7 から 11 までのバージョンでは、ユーティリティ メソッドにラップされたコンパクトで堅牢なイディオムが次のようになります。
static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
ファイルからテキスト行を読み込む
Java 7では、ファイルをテキスト行として読み込む便利な方法。として表されますList<String>
。この方法では、各行の末尾から行区切り文字が削除されるため、「損失あり」になります。
List<String> lines = Files.readAllLines(Paths.get(path), encoding);
Java 8では、Files.lines()
を生成する方法Stream<String>
。この方法でも、行区切りが削除されるため、損失が発生します。IOException
ファイルの読み取り中に が見つかった場合、それはUncheckedIOException
Stream
チェック例外をスローするラムダを受け入れないためです。
try (Stream<String> lines = Files.lines(path, encoding)) {
lines.forEach(System.out::println);
}
これStream
にはclose()
呼び出し。API のドキュメントが不十分で、メソッドがStream
あることに気付いていない人も多いのではないかと思いますclose()
。示されているように、ARM ブロックを必ず使用してください。
ファイル以外のソースを扱っている場合は、lines()
代わりにメソッドを使用しますBufferedReader
。
メモリ使用率
使用可能なメモリに比べてファイルが十分に小さい場合は、ファイル全体を一度に読み取るとうまく機能する可能性があります。ただし、ファイルが大きすぎる場合は、一度に 1 行ずつ読み取って処理し、次の行に進む前に破棄する方がよい場合があります。この方法でストリーム処理すると、メモリ要件の要因としてファイルの合計サイズが考慮されなくなります。
文字コード
元の投稿のサンプルに欠けているものの 1 つは、文字エンコーディングです。このエンコーディングは、通常、ファイル自体からは判別できず、この重要な情報を伝達するには、HTTP ヘッダーなどのメタデータが必要です。
のStandardCharsets
クラスは、すべての Java ランタイムに必要なエンコーディングの定数をいくつか定義します。
String content = readFile("test.txt", StandardCharsets.UTF_8);
プラットフォームのデフォルトは以下から入手可能ですクラスCharset
自体:
String content = readFile("test.txt", Charset.defaultCharset());
プラットフォームのデフォルトが望ましい特殊なケースがいくつかありますが、それはまれです。プラットフォームのデフォルトは移植可能ではないため、選択を正当化できる必要があります。標準入力の読み取りや標準出力の書き込みが正しい可能性がある例の 1 つは、プラットフォームのデフォルトが適切である可能性がある例です。
注: この回答は、主に Java 6 バージョンに代わるものです。Java 7 のユーティリティにより、コードが安全に簡素化され、マップされたバイト バッファを使用した古い回答では、マップされたバッファがガベージ コレクションされるまで、読み取られたファイルが削除されませんでした。この回答の「編集済み」リンクから古いバージョンを表示できます。