はじめに
IOストリームとは、データを移送するための通路です。ストリームとは、一連の流れているバイトやキャラクタを指します。JavaのIO操作は主に字节流(byte stream)とキャラクタ流(character stream)に分かれます。以下に具体的な内容を説明します。
字节流
実践例
以下の例は、画像ファイルをコピーする方法を示しています。
public static void main(String[] args) {
// 時間計測用ツール(hutoolを使用)
TimeInterval timer = DateUtil.timer();
byteFileCopy();
System.out.println("\n操作完了、所要時間:" + timer.intervalMs() + "(ミリ秒)");
}
/*
字节流を使用して非テキストファイルをコピーする方法
テキストファイルのコピーにはお勧めできません。理由は、マルチバイト文字が途中で切れると乱码が発生するためです。
*/
public static void byteFileCopy() {
final String srcFile = "F:\\logo.png"; // ソースファイル
final String targetFile = "F:\\logo1.png"; // ターゲットファイル
try (FileInputStream inputStream = new FileInputStream(srcFile);
FileOutputStream outputStream = new FileOutputStream(targetFile, false);) {
byte[] buffer = new byte[1024]; // バッファ区画の大きさ
int readLength;
while ((readLength = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, readLength);
}
// 出力バッファをフラッシュ
outputStream.flush();
} catch (IOException e) {
System.err.println("操作失敗...");
e.printStackTrace();
}
}
オブジェクトのシリアル化
以下の例は、Javaオブジェクトをファイルに保存し、復元する方法を示しています。
public static void main(String[] args) {
// 時間計測用ツール(hutoolを使用)
TimeInterval timer = DateUtil.timer();
javaObject();
System.out.println("\n操作完了、所要時間:" + timer.intervalMs() + "(ミリ秒)");
}
/*
字节流を使用してJavaオブジェクトを保存し、復元する方法
*/
public static void javaObject() {
final String targetFile = "F:\\User.txt"; // ターゲットファイル
// オブジェクトを出力
try (ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(targetFile, false));) {
final HashMap<String, Object> hashMap = new HashMap<>(4);
hashMap.put("id", "00001");
hashMap.put("age", 18);
hashMap.put("name", "山田太郎");
hashMap.put("addTime", new Date());
outputStream.writeObject(hashMap);
outputStream.flush();
} catch (IOException e) {
System.err.println("操作失敗...");
e.printStackTrace();
}
// オブジェクトを入力
try (ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(targetFile))) {
Object object = inputStream.readObject();
System.out.println(object);
} catch (IOException | ClassNotFoundException e) {
System.err.println("操作失敗...");
e.printStackTrace();
}
}
キャラクタ流
実践例
以下の例は、テキストファイルをコピーする方法を示しています。
public static void main(String[] args) {
// 時間計測用ツール(hutoolを使用)
TimeInterval timer = DateUtil.timer();
charFileCopy();
System.out.println("\n操作完了、所要時間:" + timer.intervalMs() + "(ミリ秒)");
}
/*
カラクタ流を使用してテキストファイルをコピーする方法
FileReaderやFileWriterの使用はお勧めできません。理由は、デフォルトのシステムエンコーディングを使用し、手動での指定ができないためです。
*/
public static void charFileCopy() {
final String charsetName = "GBK"; // 使用するエンコーディング
final String srcFile = "F:\\名前のない文档.txt"; // ソースファイル
final String targetFile = "F:\\コピーされた文档.txt"; // ターゲットファイル
try (InputStreamReader reader = new InputStreamReader(new FileInputStream(srcFile), charsetName);
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(targetFile), charsetName);) {
char[] buffer = new char[1024]; // バッファ区画の大きさ
int readLength;
while ((readLength = reader.read(buffer)) != -1) {
writer.write(buffer, 0, readLength);
}
// 出力バッファをフラッシュ
writer.flush();
} catch (IOException e) {
System.err.println("操作失敗...");
e.printStackTrace();
}
}
BufferedReaderの使用
以下の例は、BufferedReaderを使用してテキストを読み取る方法を示しています。
public static void main(String[] args) {
// 時間計測用ツール(hutoolを使用)
TimeInterval timer = DateUtil.timer();
charRead();
System.out.println("\n操作完了、所要時間:" + timer.intervalMs() + "(ミリ秒)");
}
/*
BufferedReaderを使用してテキストを読み取る方法
BufferedReaderは内部にバッファを保持し、行単位での読み取りが容易です。
*/
public static void charRead() {
try (BufferedReader reader = new BufferedReader(new CharArrayReader("人民英雄永垂不朽!\nheroes immortal!\n你好世界,Hello Java".toCharArray()), 1024);) {
// バッファ全体を読んでみる
char[] buffer = new char[1024];
int readLength;
while ((readLength = reader.read(buffer)) != -1) {
System.out.print(new String(buffer, 0, readLength));
}
// 行単位で読んでみる
String line;
while ((line = reader.readLine()) != null) {
System.out.print(line + "\n");
}
// Streamに変換して操作する
reader.lines().forEach(line1 -> {
System.out.print(line1 + "\n");
});
} catch (IOException e) {
System.err.println("操作失敗...");
e.printStackTrace();
}
}
更新
2022-03-09更新:ディレクトリ内のすべてのファイルを削除する方法
public static void main(String[] args) {
String path = "E:\\abc"; // ディレクトリ
// ディレクトリ内のすべてのファイル、サブディレクトリを削除
deleteAllFile(new File(path));
// 空のディレクトリを作成
new File(path).mkdir();
System.out.println("操作完了!");
}
// ファイルやディレクトリを再帰的に削除するメソッド
private static void deleteAllFile(File file) {
if (file.isFile()) {
file.delete();
} else if (file.isDirectory()) {
File[] files = Objects.requireNonNull(file.listFiles());
for (File f : files) {
deleteAllFile(f);
}
file.delete();
}
}
おわりに
キャンペーン
- テキストファイルのコピーにはキャラクタ流を使用することを推奨します。字节流を使用するとマルチバイト文字が途中で切れ、乱码が発生する可能性があります。
- テキストファイルの操作ではFileReaderやFileWriterを使用しないでください。理由は、デフォルトのシステムエンコーディングを使用し、手動での指定ができないためです。代わりにBufferedReaderを使用してください。
- ObjectOutputStreamを使用してJavaオブジェクトを保存し、復元することは便利な技術です。必要に応じて活用してください。
以上、JavaのIOストリームについての基礎的内容をご紹介しました。