在 Java 開發中,檔案與位元組陣列的互轉是基礎且關鍵的操作。無論是處理二進制資料、網路傳輸還是本地快取,掌握高效的讀寫方式都能顯著提升程式效能。本文將詳細解析兩種主流的檔案讀取策略,以及位元組陣列寫入檔案的標準實作。
此方式直接根據檔案大小分配位元組陣列,透過 FileInputStream 一次性讀取所有內容。程式碼會檢查檔案大小是否超過 Integer.MAX_VALUE,並透過迴圈確保所有資料完整讀入緩衝區。
public byte[] getContent(String filePath) throws IOException {
File file = new File(filePath);
long fileSize = file.length();
if (fileSize > Integer.MAX_VALUE) {
System.out.println("檔案過大,無法一次性讀取");
return null;
}
try (FileInputStream fis = new FileInputStream(file)) {
byte[] buffer = new byte[(int) fileSize];
int offset = 0, numRead;
while (offset < buffer.length && (numRead = fis.read(buffer, offset, buffer.length - offset)) >= 0) {
offset += numRead;
}
if (offset != buffer.length) {
throw new IOException("無法完整讀取檔案: " + file.getName());
}
return buffer;
}
}
優點: 程式碼簡潔,適合記憶體足夠且檔案較小的場景。
缺點: 大檔案會導致 OutOfMemoryError,不適合超過 2GB 的檔案。
利用 ByteArrayOutputStream 搭配固定大小緩衝區(如 1KB),循環讀取並寫入輸出流,最後轉為位元組陣列。此法不受檔案大小限制,記憶體佔用穩定。
public byte[] getContent2(String filePath) throws IOException {
try (FileInputStream fis = new FileInputStream(filePath);
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024)) {
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
return baos.toByteArray();
}
}
優點: 記憶體佔用可控,支援任意大小檔案。
缺點: 相比一次性讀取,多一次記憶體複製(toByteArray())。
使用 FileOutputStream 直接將位元組陣列寫入磁碟,建議搭配 try-with-resources 確保資源釋放。
public void createFile(String path, byte[] content) throws IOException {
try (FileOutputStream fos = new FileOutputStream(path)) {
fos.write(content);
}
}
try-with-resources 管理流資源,並在適當層級處理異常。MappedByteBuffer 或分片處理,而非全量載入記憶體。掌握這兩種核心模式,能讓你在不同業務場景下靈活選擇最適合的檔案讀寫策略,打造穩健高效的 Java 應用。