ファイルIO
ファイル操作はプログラムの重要な機能です。このレッスンでは、JavaのファイルIOを学びます。
Fileクラス
Fileクラスはファイルやディレクトリを操作するために使用されます。
Fileオブジェクトの作成
JAVA
import java.io.File;
// 方法1:パス文字列
File file1 = new File("test.txt");
// 方法2:親パス + ファイル名
File file2 = new File("/home/user", "test.txt");
// 方法3:Fileオブジェクト + ファイル名
File dir = new File("/home/user");
File file3 = new File(dir, "test.txt");
一般的なメソッド
| メソッド | 説明 |
|---|---|
exists() |
存在するか |
isFile() |
ファイルか |
isDirectory() |
ディレクトリか |
getName() |
ファイル名を取得 |
getPath() |
パスを取得 |
getAbsolutePath() |
絶対パスを取得 |
length() |
ファイルサイズ(バイト) |
createNewFile() |
ファイルを作成 |
mkdir() |
ディレクトリを作成 |
mkdirs() |
ネストされたディレクトリを作成 |
delete() |
削除 |
list() |
ディレクトリの内容を一覧表示 |
例:ファイル操作
JAVA
import java.io.File;
import java.io.IOException;
public class FileDemo {
public static void main(String[] args) throws IOException {
File file = new File("test.txt");
// ファイルを作成
if (!file.exists()) {
file.createNewFile();
System.out.println("ファイルが正常に作成されました");
}
// ファイル情報
System.out.println("ファイル名: " + file.getName());
System.out.println("パス: " + file.getPath());
System.out.println("絶対パス: " + file.getAbsolutePath());
System.out.println("サイズ: " + file.length() + " バイト");
System.out.println("ファイルか: " + file.isFile());
System.out.println("ディレクトリか: " + file.isDirectory());
// ファイルを削除
// file.delete();
}
}
例:ディレクトリ操作
JAVA
import java.io.File;
public class DirectoryDemo {
public static void main(String[] args) {
// ディレクトリを作成
File dir = new File("testdir/subdir");
dir.mkdirs();
System.out.println("ディレクトリが作成されました: " + dir.getAbsolutePath());
// ディレクトリの内容を一覧表示
File parent = new File("testdir");
String[] files = parent.list();
if (files != null) {
for (String name : files) {
System.out.println(" " + name);
}
}
// ディレクトリを走査
File[] fileArray = parent.listFiles();
if (fileArray != null) {
for (File f : fileArray) {
String type = f.isDirectory() ? "[DIR]" : "[FILE]";
System.out.println(type + " " + f.getName());
}
}
}
}
ファイル読み書き
BufferedReaderによるファイル読み取り
JAVA
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFile {
public static void main(String[] args) {
// try-with-resourcesでリソースを自動閉じる
try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("読み取り失敗: " + e.getMessage());
}
}
}
BufferedWriterによるファイル書き込み
JAVA
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class WriteFile {
public static void main(String[] args) {
// 上書き
try (BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
writer.write("Hello, World!");
writer.newLine();
writer.write("Javaファイル操作");
System.out.println("書き込み成功");
} catch (IOException e) {
System.out.println("書き込み失敗: " + e.getMessage());
}
// 追記
try (BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt", true))) {
writer.write("追加コンテンツ");
writer.newLine();
System.out.println("追加成功");
} catch (IOException e) {
System.out.println("追加失敗: " + e.getMessage());
}
}
}
try-with-resources
Java 7で導入され、AutoCloseableを実装したリソースを自動的に閉じます。
構文
JAVA
try (リソース型 変数 = new リソース()) {
// リソースを使用
} catch (例外型 e) {
// 例外を処理
}
例:ファイルコピー
JAVA
import java.io.*;
public class FileCopy {
public static void copy(String src, String dest) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(src));
BufferedWriter writer = new BufferedWriter(new FileWriter(dest))) {
String line;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine();
}
}
System.out.println("コピー完了");
}
public static void main(String[] args) {
try {
copy("source.txt", "dest.txt");
} catch (IOException e) {
System.out.println("コピー失敗: " + e.getMessage());
}
}
}
すべての内容を読み取る
方法1:行ごとに読み取る
JAVA
public static String readAll(String filename) throws IOException {
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
}
return sb.toString();
}
方法2:Filesユーティリティクラス(Java 7+)
JAVA
import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.IOException;
import java.util.List;
public class FilesDemo {
public static void main(String[] args) throws IOException {
// すべての行を読み取る
List<String> lines = Files.readAllLines(Paths.get("test.txt"));
lines.forEach(System.out::println);
// 文字列として読み取る
String content = new String(Files.readAllBytes(Paths.get("test.txt")));
System.out.println(content);
// ファイルに書き込む
Files.write(Paths.get("output.txt"), "Hello".getBytes());
}
}
ファイル走査
再帰的なディレクトリ一覧
JAVA
import java.io.File;
public class ListFiles {
public static void listFiles(File dir, String indent) {
File[] files = dir.listFiles();
if (files == null) return;
for (File file : files) {
System.out.println(indent + file.getName());
if (file.isDirectory()) {
listFiles(file, indent + " ");
}
}
}
public static void main(String[] args) {
File dir = new File(".");
listFiles(dir, "");
}
}
ファイルフィルタリング
JAVA
import java.io.File;
import java.io.FilenameFilter;
public class FileFilter {
public static void main(String[] args) {
File dir = new File(".");
// .txtファイルのみ一覧表示
String[] txtFiles = dir.list((d, name) -> name.endsWith(".txt"));
if (txtFiles != null) {
for (String name : txtFiles) {
System.out.println(name);
}
}
// ディレクトリのみ一覧表示
File[] dirs = dir.listFiles(File::isDirectory);
if (dirs != null) {
for (File d : dirs) {
System.out.println("[DIR] " + d.getName());
}
}
}
}
シリアライゼーション
オブジェクトをバイトストリームに変換し、ファイルへの保存やネットワーク送信を可能にします。
シリアライゼーションの要件
- クラスは
Serializableインターフェースを実装する必要がある - すべてのフィールドもシリアライズ可能でなければならない
例:シリアライゼーション
JAVA
import java.io.*;
// シリアライズ可能なクラス
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
private transient String password; // transientはシリアライゼーションから除外
public User(String name, int age, String password) {
this.name = name;
this.age = age;
this.password = password;
}
@Override
public String toString() {
return "User{name='" + name + "', age=" + age + ", password='" + password + "'}";
}
}
public class SerializeDemo {
public static void main(String[] args) {
// シリアライズ
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.dat"))) {
User user = new User("Alice", 25, "123456");
oos.writeObject(user);
System.out.println("シリアライズ成功");
} catch (IOException e) {
System.out.println("シリアライズ失敗: " + e.getMessage());
}
// デシリアライズ
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.dat"))) {
User user = (User) ois.readObject();
System.out.println("デシリアライズ: " + user);
// User{name='Alice', age=25, password='null'}(パスワードは除外)
} catch (IOException | ClassNotFoundException e) {
System.out.println("デシリアライズ失敗: " + e.getMessage());
}
}
}
❓ よくある質問
Q 相対パスと絶対パスの違いは何ですか?
A 相対パスは現在の作業ディレクトリからの相対パスです。絶対パスはルートディレクトリから始まります。
Q なぜtry-with-resourcesを使用するのですか?
A リソースを自動的に閉じ、リソースリークを防止します。手動のfinallyより簡潔です。
Q transientキーワードは何をしますか?
A シリアライゼーションに参加すべきでないフィールドをマークします。
📖 まとめ
- Fileクラスはファイルとディレクトリを操作する
- BufferedReader/BufferedWriterでファイルを読み書き
- try-with-resourcesでリソースを自動的に閉じる
- Filesユーティリティクラスでファイル操作を簡素化
- シリアライゼーションでオブジェクトをファイルに保存
📝 演習
- ファイル統計: ファイル内の行数、単語数、文字数をカウント
- ファイルコピー: 大きなファイルをサポートするファイルコピーを実装
- ディレクトリ走査: ディレクトリ内のすべてのファイルを再帰的に一覧表示し、サイズでソート
次のレッスン
次のレッスンでは、ストリームとNIOを学びます — JavaのストリームベースIO。



