到達点は、外部のデータを明示的な形式で読み書きすることです。前提は第08回です。
ファイルには文字コードが必要
ファイルの実体はバイト列です。文字列へ戻す規則が文字コードです。UTF-8を明示すると、別のマシンでも意図が伝わります。Pathは場所を表し、Filesが読み書きなどの操作を提供します。
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.time.*;
public class Main {
public static void main(String[] args) throws Exception {
Path file = Files.createTempFile("study-", ".txt");
try {
Files.writeString(file, "Java\nRust\n", StandardCharsets.UTF_8);
try (var lines = Files.lines(file, StandardCharsets.UTF_8)) {
System.out.println(lines.filter(s -> !s.isBlank()).count());
}
Instant instant = Instant.parse("2026-01-01T00:00:00Z");
System.out.println(instant.atZone(ZoneId.of("Asia/Tokyo")));
System.out.println(LocalDate.of(2026, 1, 31).plusDays(1));
} finally {
Files.deleteIfExists(file);
}
}
}
Main.javaで実行すると行数は2、時刻は日本時間の9時、日付は2026年2月1日です。実習では自分で作った一時ファイルだけを削除します。Files.linesが返すStreamも、ファイルを開いているため閉じる必要があります。
日付、現地時刻、瞬間を区別する
LocalDateは年月日、LocalDateTimeはタイムゾーンなしの日時、Instantは時間軸上の瞬間です。利用者の地域で表示するときにZoneIdを使います。ログの発生時刻と誕生日を同じ型で扱う必要はありません。
「24時間後」と「翌日の同じ現地時刻」は、夏時間のある地域では一致しないことがあります。期間や期限は利用者の期待に合わせて定義します。現在時刻に依存するテストではClockを外から渡すと、日付が変わっても再現できます。
練習と解答
練習:巨大なファイルの行数を数える場合、readStringで一度に読む方法とFiles.linesの違いを説明します。
解答:readStringは全内容をメモリへ読み込みます。Files.linesは逐次処理に向きますが、途中でtoListを呼べば再び全件を保持します。文字列の分割だけでCSVを自作すると、引用符や改行を含む項目を壊しやすいため、形式に合うライブラリを選びます。
保存の途中で障害が起きると内容が欠ける可能性があります。重要な保存では、一時ファイルへの書き込み後の置き換えやデータベースのトランザクションを検討します。原子性と、停電後も残る耐久性は別の保証です。
公式資料
Java全20回の目次 | 前の回 | 次の回