😊
【Java】ファイルの読み書きまとめ
ファイルの読み書きについて
- Java では、java.io や java.nio パッケージを使ってファイルの読み書きを行うことができます。
- ファイル操作には主に 「文字(テキスト)データの処理」 と 「バイナリデータ(画像や音声など)の処理」 があります。
文字データの読み書き
文字データ(テキストファイル)の読み書きには、以下のクラスを使用します。
書き込み
- FileWriter:文字をファイルに書き込む
- BufferedWriter:バッファを使用するので、効率よく書き込むことができる
読み込み
- FileReader:ファイルを文字単位で読み込む
- BufferedReader:バッファを使用するので、効率よく読み込むことができる
文字の書き込み(基本的な方法)
- シンプルな構文でファイルに文字を書き込める。
- FileWriter(String, true) で追記モードが可能。
- 文字を直接ディスクに書き込むため 遅い(バッファリングがない)
package fileTest;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriteExample {
public static void main(String[] args) {
//ファイルを開く
//new FileWriter("test.txt", true) とすると追記モードになる
try (FileWriter fw = new FileWriter("test.txt")) {
//ファイルに書き込む
fw.write("こんにちは、Javaファイルの書き込み!\n");
fw.write("2行目のテスト");
} catch (IOException e) {
e.printStackTrace();
}
}
}
test.txt
こんにちは、Javaファイルの書き込み!
2行目のテスト
java.nio.file.Filesを使用した場合
- シンプルなコードでファイル書き込みが可能。
- リストの内容を 一括で書き込みできる。
- Files.write() は 全データを一括で書き込むのでメモリの消費が大きい
- ディスク容量不足などで途中で異常が発生した場合にデータの一部しか書き込まれない可能性がある
- 既存の内容を上書きする。追記したい場合はStandardOpenOption.APPENDを- Files.write() の第3引数に指定する
package fileTest;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
public class FilesWriteExample {
public static void main(String[] args) {
try {
//Files.write() は リスト (List<String>) を渡すと、複数行を書き込める
//Paths.get("test.txt") でファイルのパスを指定
Files.write(Paths.get("filesWrite.txt"), Arrays.asList(
"こんにちは、Javaファイルの書き込み!",
"2行目のテスト"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
文字の書き込み(BufferedWriter を使う)
- バッファリングにより、複数回の書き込みをまとめて処理し 効率が良い。
- newLine() メソッドで改行が簡単にできる。
- 大きなファイルを扱うなら、BufferedWriter を使って ストリームで少しずつ書き込む のが良い
- BufferedWriter を使うために FileWriter が必要(若干コードが長くなる)。
package fileTest;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedWriteExample {
public static void main(String[] args) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter("bufferedWrite.txt"))) {
bw.write("バッファ付きで書き込み\n");
bw.write("効率的なファイル書き込み");
} catch (IOException e) {
e.printStackTrace();
}
}
}
bufferedWrite.txt
バッファ付きで書き込み
効率的なファイル書き込み
文字の書き込み(PrintWriter を使う)
- println() で簡単に改行できる。
- printf() でフォーマット出力が可能。
- BufferedWriter と同様にバッファを持っており、効率的。
- BufferedWriter に比べて、処理が遅くなることがある。
package fileTest;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class PrintWriteExample {
public static void main(String[] args) {
try (PrintWriter pw = new PrintWriter(new FileWriter("printWrite.txt"))) {
pw.println("PrintWriter を使用して書き込み");
pw.println(123); // 数値も直接書ける
pw.printf("フォーマット出力: %.2f", 3.1415);
} catch (IOException e) {
e.printStackTrace();
}
}
}
printWrite.txt
PrintWriter を使用して書き込み
123
フォーマット出力: 3.14
文字の読み込み(基本的な方法)
- シンプルなコードで1文字ずつ読み込める。
- 1文字ずつしか読めないため、処理が遅い。(BufferedReader を使う方が一般的。)
package fileTest;
import java.io.FileReader;
import java.io.IOException;
public class FileReadExample {
public static void main(String[] args) {
//fileRead.txtを開く(ファイルは用意しておく)
try (FileReader fr = new FileReader("fileRead.txt")) {
int c;
while ((c = fr.read()) != -1) { // 1文字ずつ読み込む
System.out.print((char) c);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
fileRead.txt
こんにちは、Javaファイルの書き込み!
2行目のテスト
<出力例>
こんにちは、Javaファイルの書き込み!
2行目のテスト
java.nio.file.Filesを使用した場合
- 簡単にファイルを一括読み込みできる。
- List<String> に変換されるので 処理がしやすい。
- 大きなファイルには不向き(全データをメモリにロードするため)。
package fileTest;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
public class FilesReadExample {
public static void main(String[] args) {
try {
//全行をリストに取得
List<String> lines = Files.readAllLines(Paths.get("filesRead.txt"));
lines.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
}
文字の読み込み(BufferedReader を使う)
- 1行ずつ読み込めるので、FileReader より高速。
- バッファリングによって効率的。
- BufferedReader のインスタンス作成のコードが FileReader より少し長い。
package fileTest;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReadExample {
public static void main(String[] args) {
//bufferedRead.txtを開く(ファイルは用意しておく)
try (BufferedReader br = new BufferedReader(new FileReader("bufferedRead.txt"))) {
String line;
while ((line = br.readLine()) != null) { // 1行ずつ読み込む
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
bufferedRead.txt
バッファ付きで書き込み
効率的なファイル書き込み
<出力例>
バッファ付きで書き込み
効率的なファイル書き込み
バイナリデータの読み書き
画像・音声・動画などのバイナリデータを扱う場合、InputStream / OutputStream を使用します。
書き込み
FileOutputStream:バイナリデータを書き込む
BufferedOutputStream:バッファを使用するので効率よく書き込む
読み込み
FileInputStream:バイナリデータを読み込む
BufferedInputStream:バッファを使用するので効率よく読み込む
バイナリデータの書き込み(FileOutputStream)
- 1バイトずつ書き込むので非効率(BufferedOutputStream の方が速い)。
- テキストファイルには不向き(文字エンコーディングの処理がない)。
例)ファイルに「ABCDE」と書き込む
package fileTest;
import java.io.FileOutputStream;
import java.io.IOException;
public class BinaryWriteExample {
public static void main(String[] args) {
byte[] data = { 65, 66, 67, 68, 69 }; // A, B, C, D, E
try (FileOutputStream fos = new FileOutputStream("binary.dat")) {
fos.write(data);
} catch (IOException e) {
e.printStackTrace();
}
}
}
バイナリデータの書き込み(BufferedOutputStream)
- バッファを使用して 書き込み効率が向上(複数回の書き込みをまとめて処理)。
- BufferedOutputStream のインスタンス作成が若干面倒。
package fileTest;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedOutputStreamExample {
public static void main(String[] args) {
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bufferedOutputStream.dat"))) {
//ABCと書き込む
bos.write(new byte[] { 65, 66, 67 });
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
バイナリデータの読み込み(FileInputStream)
- 1バイトずつ読むため、処理が遅い。
- BufferedInputStream の方が効率が良い。
package fileTest;
import java.io.FileInputStream;
import java.io.IOException;
public class BinaryReadExample {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("binary.dat")) {
int byteData;
while ((byteData = fis.read()) != -1) {
System.out.print((char) byteData);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
<出力例>
ABCDE
バイナリデータの読み込み(BufferedInputStream)
- バッファリングにより、FileInputStream より高速。
- BufferedInputStream を作成する手間がある。
package fileTest;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class BufferedInputStreamExample {
public static void main(String[] args) {
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bufferedOutputStream.dat"))) {
int b;
while ((b = bis.read()) != -1) {
System.out.print((char) b);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
<出力例>
ABC
まとめ
大きなデータを扱う場合は Buffered 系を、簡単な処理なら Files クラスを活用する
- 基本的な文字の書き込み → BufferedWriter
- 簡単な改行やフォーマットが必要 → PrintWriter
- 基本的な文字の読み込み → BufferedReader
- バイナリデータの書き込み → BufferedOutputStream
- バイナリデータの読み込み → BufferedInputStream
- シンプルなファイル処理がしたい → Files.write() / Files.readAllLines()
Discussion