特定ディレクトリ配下にあるファイルを読み込んでフンタラする昔ながらにある処理を
java8で書いてる時に気づいた点です。
書き方によって例外が発生したりしなかったり
テストファイル一つだけで試してたので気づかなかったのですが
あちこちからかき集めた大量のファイルで試してみたらmalformedInputExceptionでコケたので
まとめてみました。
public static void main(String[] args) throws IOException {
// ① CharsetDecoderはデフォルトでCodingErrorAction.REPORT
try (Stream<String> lines = Files.lines(Paths.get("test.txt"))) {
lines.forEach(s -> {
System.out.println(s);
});
} catch (Exception e) {
System.out.println("例外発生");
}
// ② CharsetDecoderはデフォルトでCodingErrorAction.REPORT
try (BufferedReader br = Files.newBufferedReader(Paths.get("test.txt"));
Stream<String> lines = br.lines()){
lines.forEach(s -> {
System.out.println(s);
});
} catch (Exception e) {
System.out.println("例外発生");
}
// ③ CharsetDecoderはデフォルトでCodingErrorAction.REPLACE
try (BufferedReader br = new BufferedReader(new FileReader(new File("test.txt")));
Stream<String> lines = br.lines();) {
lines.forEach(s -> {
System.out.println(s);
});
System.out.println("文字化けするが例外起きない");
} catch (Exception e) {
System.out.println("例外起きない");
}
// ④ CharsetDecoderはデフォルトでCodingErrorAction.REPLACE
CharsetDecoder dec = StandardCharsets.UTF_8.newDecoder().onMalformedInput(CodingErrorAction.IGNORE);
try (Reader r = Channels.newReader(FileChannel.open(Paths.get("test.txt")), dec, -1);
BufferedReader br = new BufferedReader(r);
Stream<String> lines = br.lines();) {
lines.forEach(s -> {
System.out.println(s);
});
System.out.println("文字化けするが例外起きない");
} catch (Exception e) {
System.out.println("例外起きない");
}
}
読み込むファイルのエンコードが確定している時は指定すれば良いと思うのですが、
いろいろ混じるときは特定する処理が必要ですね。