1日目のゴール
1日目のテーマは
「ファイルに“文字”を書いて、“あとから読み返せる”感覚をつかむこと」 です。
今日はまだ「完璧な設計」は目指しません。
まずはこう思えたら勝ちです。
「メモをファイルに保存して、プログラムを終了しても残っている」
「次に起動したとき、そのメモを読み込める」
これが「永続化(えいぞくか)」の一番シンプルな姿です。
永続化って何?メモ帳との違いから考える
メモリは「消える世界」、ファイルは「残る世界」
Java のプログラムが動いているとき、
変数やオブジェクトは「メモリ」という場所に置かれています。
String memo = "こんにちは";
と書けば、memo という変数に文字列が入りますが、
プログラムを終了した瞬間、それは消えます。
一方、ファイルはこうです。
テキストファイルに「こんにちは」と書いて保存する
パソコンを再起動しても、そのファイルは残っている
この「プログラムが終わっても残る」ことを
永続化(えいぞくか) と呼びます。
なぜ永続化が必要なのか
ToDo アプリ、日記アプリ、家計簿アプリ…
どれも「次に開いたときに前のデータが残っていてほしい」ですよね。
メモリだけに持っていると、
アプリを閉じた瞬間に全部消えてしまいます。
だから、
アプリの中のデータ
→ ファイル(またはデータベース)に書き出す
→ 次回起動時に読み込む
という流れが必要になります。
1日目は、その「一番小さい版」として、
テキストファイルへの保存と読み込み をやります。
今日の題材:1行メモを保存・読み込みするミニアプリ
何を作るか
コンソールで動く、超シンプルなアプリを作ります。
メニューを表示する
「1: メモを保存」「2: メモを読み込み」「0: 終了」
保存では、1行のメモを入力してファイルに書き込む
読み込みでは、そのファイルから1行読み出して表示する
まずは「1行だけ」でいいです。
ここで大事なのは、
「書いたものが、プログラムを終了しても残る」 という体験です。
ファイルに書き込む基本:FileWriter と BufferedWriter
まずは「書き込みだけ」のサンプル
ファイルに文字を書き込む最小コードを見てみましょう。
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class SimpleWrite {
public static void main(String[] args) {
String fileName = "memo.txt";
String text = "こんにちは、ファイル保存!";
try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
writer.write(text);
writer.newLine(); // 改行を入れる(おまけ)
System.out.println("書き込みが完了しました。");
} catch (IOException e) {
System.out.println("ファイルへの書き込みに失敗しました。");
System.out.println("(開発者向け情報)" + e.getMessage());
}
}
}
Javaここで出てきたクラスを、かみ砕いて説明します。
FileWriter と BufferedWriter の役割
FileWriter
指定したファイルに「文字」を書くためのクラスです。new FileWriter("memo.txt") とすると、
カレントディレクトリに memo.txt というファイルを開きます(なければ作る)。
BufferedWriterFileWriter に「バッファ(クッション)」をつけて、
効率よく書き込むためのクラスです。
細かいことは今は気にしなくてOKで、
「FileWriter を包んで使うのが定番」と覚えておけば十分です。
try-with-resources の意味(超重要)
try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
// 書き込み処理
}
Javaこの書き方は try-with-resources と呼ばれます。
ポイントは一つ。
ブロックを抜けるときに、自動で writer.close() してくれる
ファイルやネットワークのような「開いたら閉じる必要があるもの」は、
閉じ忘れると不具合の原因になります。
try-with-resources を使うと、
例外が起きても起きなくても、
最後に必ず close してくれるので、とても安全です。
ファイルから読み込む基本:FileReader と BufferedReader
「読み込みだけ」のサンプル
次は、ファイルから1行読み込むコードです。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class SimpleRead {
public static void main(String[] args) {
String fileName = "memo.txt";
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String line = reader.readLine();
if (line == null) {
System.out.println("ファイルは空です。");
} else {
System.out.println("読み込んだ内容: " + line);
}
} catch (IOException e) {
System.out.println("ファイルの読み込みに失敗しました。");
System.out.println("(開発者向け情報)" + e.getMessage());
}
}
}
JavaFileReader と BufferedReader の役割
FileReader
指定したファイルから「文字」を読み込むためのクラスです。
BufferedReaderFileReader を包んで、readLine() で「1行ずつ」読み込めるようにしてくれるクラスです。
readLine() は、
行があれば、その行の文字列を返す
ファイルの終わりまで来たら null を返す
という動きをします。
1日目では、
「とりあえず1行だけ読む」
という使い方で十分です。
保存アプリ1日目版:1行メモ保存+読み込み
全体のイメージ
ここまでの部品を組み合わせて、
1日目の「ファイル保存アプリ」を作ります。
やることはシンプルです。
メニューを表示
1 → メモを入力して保存
2 → 保存されたメモを読み込み
0 → 終了
コードを見てから、重要ポイントを解説します。
コード全体
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
public class FileSaveApp {
private static final String FILE_NAME = "memo.txt";
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println();
System.out.println("=== ファイル保存アプリ 1日目 ===");
System.out.println("1: メモを保存");
System.out.println("2: メモを読み込み");
System.out.println("0: 終了");
System.out.print("番号を選んでください: ");
String choice = scanner.nextLine();
if ("0".equals(choice)) {
System.out.println("終了します。");
break;
} else if ("1".equals(choice)) {
saveMemo(scanner);
} else if ("2".equals(choice)) {
loadMemo();
} else {
System.out.println("不正な入力です。0, 1, 2 のいずれかを入力してください。");
}
}
scanner.close();
}
private static void saveMemo(Scanner scanner) {
System.out.print("保存したいメモを1行で入力してください: ");
String memo = scanner.nextLine();
if (memo.isEmpty()) {
System.out.println("空のメモは保存しません。");
return;
}
try (BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_NAME))) {
writer.write(memo);
writer.newLine();
System.out.println("メモをファイルに保存しました。ファイル名: " + FILE_NAME);
} catch (IOException e) {
System.out.println("メモの保存に失敗しました。");
System.out.println("(開発者向け情報)" + e.getMessage());
}
}
private static void loadMemo() {
try (BufferedReader reader = new BufferedReader(new FileReader(FILE_NAME))) {
String line = reader.readLine();
if (line == null) {
System.out.println("ファイルは空です。まだメモが保存されていません。");
} else {
System.out.println("保存されているメモ: " + line);
}
} catch (IOException e) {
System.out.println("メモの読み込みに失敗しました。まだ保存されていないか、ファイルにアクセスできません。");
System.out.println("(開発者向け情報)" + e.getMessage());
}
}
}
Java重要ポイントをかみ砕いて解説する
1つのファイル名を定数で持つ
private static final String FILE_NAME = "memo.txt";
Javaここは地味ですが、かなり大事です。
ファイル名をあちこちにベタ書きすると、
後で名前を変えたくなったときに全部直す必要が出てきます。
FILE_NAME という定数にしておけば、
「どのファイルに保存しているか」が一目で分かるし、
変更も1か所で済みます。
保存処理:上書き保存のシンプル版
try (BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_NAME))) {
writer.write(memo);
writer.newLine();
System.out.println("メモをファイルに保存しました。ファイル名: " + FILE_NAME);
} catch (IOException e) {
System.out.println("メモの保存に失敗しました。");
System.out.println("(開発者向け情報)" + e.getMessage());
}
Javaここでのポイントは二つです。
new FileWriter(FILE_NAME) は「上書きモード」
→ すでにファイルがあれば中身を消して書き直す
→ 1日目は「最新の1件だけ保存」で十分
try-with-resources で writer を自動 close
→ 閉じ忘れを防げる
→ 例外が起きても確実に片付く
「追記モード(append)」は、new FileWriter(FILE_NAME, true) と書きますが、
それは2日目以降のテーマに回しましょう。
読み込み処理:ファイルが空のときの扱い
String line = reader.readLine();
if (line == null) {
System.out.println("ファイルは空です。まだメモが保存されていません。");
} else {
System.out.println("保存されているメモ: " + line);
}
JavareadLine() が null を返すのは、
「ファイルの終わりまで来た」ことを意味します。
1日目のアプリでは、
ファイルが存在するが中身が空 → 「まだメモが保存されていません」と表示
1行以上あれば、最初の1行だけ表示
というシンプルな仕様にしています。
例外メッセージの扱い(軽くおさらい)
} catch (IOException e) {
System.out.println("メモの読み込みに失敗しました。まだ保存されていないか、ファイルにアクセスできません。");
System.out.println("(開発者向け情報)" + e.getMessage());
}
Javaユーザー向けには、
「何が起きたか」「どういう可能性があるか」をざっくり伝える。
開発者向けには、e.getMessage() で技術的な詳細を表示する。
本番アプリなら、
この「開発者向け情報」はログに出すことが多いです。
1日目で“体に入れてほしい感覚”
「メモリの中」と「ファイルの中」を意識して分ける
このアプリで起きていることを、
頭の中で二つの世界に分けてみてください。
プログラムが動いている間だけの世界(メモリ)
Scanner で入力した文字列memo 変数の中身
プログラムが終わっても残る世界(ファイル)memo.txt の中に書かれた文字
writer.write(memo); の一行は、
「メモリの中の文字列を、ファイルという“残る世界”にコピーする」
という意味です。
逆に reader.readLine(); は、
「ファイルという“残る世界”から、メモリに1行分コピーする」
という意味です。
このイメージが持てたら、
もう永続化の入り口には立てています。
1日目のまとめと、次へのつながり
今日は、
ファイルに文字を書き込む(FileWriter / BufferedWriter)
ファイルから文字を読み込む(FileReader / BufferedReader)
try-with-resources で「開いたら閉じる」を自動化する
1行メモを保存・読み込みするミニアプリを作る
ところまで来ました。
ここから先は、例えばこんな方向に広げていけます。
複数行のメモを保存する(追記モード)
ToDo リストを1行1タスクで保存する
「保存」と「読み込み」を例外処理と組み合わせて堅くする
でも、1日目で一番大事なのは、
「あ、ファイルに書いたら、本当に残るんだ」
という小さな感動です。
そこさえつかめていれば、
あとは「何を保存したいか」を変えていくだけで、
どんどんアプリっぽいものが作れるようになります。

