バッファ操作の基本
ファイルデータの読み込みにはFileChannelとByteBufferの組み合わせが有効です。以下の例ではファイルからデータを読み込み、バッファ経由でコンソールに出力する処理を実装しています。
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class FileReadExample {
public static void main(String[] args) {
try (FileChannel fileChannel = new FileInputStream("input.txt").getChannel()) {
ByteBuffer buffer = ByteBuffer.allocate(16);
// データ読み込みとバッファへの格納
int bytesRead = fileChannel.read(buffer);
while (bytesRead != -1) {
buffer.flip();
// バッファ内容の文字列出力
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}
buffer.clear();
bytesRead = fileChannel.read(buffer);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
マルチバッファ処理の応用
複数のByteBufferを使用してファイルデータを分割処理する場合、以下のような実装が可能です。
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.io.RandomAccessFile;
import java.io.IOException;
public class MultiBufferExample {
public static void main(String[] args) {
try (RandomAccessFile file = new RandomAccessFile("data.bin", "r")) {
FileChannel channel = file.getChannel();
// 複数バッファの準備
ByteBuffer header = ByteBuffer.allocate(8);
ByteBuffer payload = ByteBuffer.allocate(1024);
// チャンネルからの分散読み込み
channel.read(new ByteBuffer[]{header, payload});
// 各バッファの内容確認
header.flip();
payload.flip();
// バッファ内容のデバッグ表示
System.out.println("ヘッダサイズ: " + header.remaining());
System.out.println("ペイロードサイズ: " + payload.remaining());
} catch (IOException e) {
e.printStackTrace();
}
}
}
大容量ファイル処理
サイズがInteger.MAX_VALUEを超えるファイルの転送には、以下のサンプルコードのように部分転送の仕組みを実装する必要があります。
import java.nio.channels.FileChannel;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class LargeFileTransfer {
public static void main(String[] args) {
try (FileChannel source = new FileInputStream("large.bin").getChannel();
FileChannel target = new FileOutputStream("backup.bin").getChannel()) {
long totalSize = source.size();
long position = 0;
// チャンク単位での転送処理
while (position < totalSize) {
long remaining = totalSize - position;
long chunkSize = Math.min(remaining, Integer.MAX_VALUE);
position += source.transferTo(position, chunkSize, target);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
ファイルシステム操作
ファイルツリーの走査にはFiles.walkFileTreeメソッドを使用します。以下の例は特定拡張子のファイルのみを検索する実装例です。
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
public class JarFileSearch {
public static void main(String[] args) {
try {
Files.walkFileTree(Paths.get("/opt/java/libs"), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
if (file.toString().endsWith(".jar")) {
System.out.println("見つかったJAR: " + file);
}
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
ファイル操作ユーティリティ
ディレクトリのコピー処理を実装する場合、以下のようなコードで再帰的なコピーが可能です。
import java.io.IOException;
import java.nio.file.*;
public class DirectoryCopier {
public static void main(String[] args) {
Path sourceDir = Paths.get("/var/data/source");
Path targetDir = Paths.get("/backup/dest");
try {
Files.walk(sourceDir).forEach(path -> {
try {
Path targetPath = targetDir.resolve(sourceDir.relativize(path));
if (Files.isDirectory(path)) {
Files.createDirectories(targetPath);
} else {
Files.copy(path, targetPath, StandardCopyOption.REPLACE_EXISTING);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}