位元組流(InputStream/OutputStream 子類)專為處理二進位資料設計:圖片、影片、音訊、壓縮檔等非文字檔案。複製此類檔案必須使用位元組流,不可使用字元流(Reader/Writer),否則會導致檔案損毀。
package learn;
import java.io.*;
public class Learn {
public static void main(String[] args) throws IOException {
File src = new File("D:/a.jpg");
File dest = new File("D:/b.jpg");
// 依檔案大小建立緩衝陣列
byte[] buffer = new byte[(int) src.length()];
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream(src);
out = new FileOutputStream(dest); // 目標不存在會自動建立
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead); // 關鍵:寫入實際讀取長度
}
out.flush(); // 強制刷新緩衝區
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
// 確保資源釋放
if (in != null) in.close();
if (out != null) out.close();
}
}
}
範例使用檔案長度建立陣列,適合中小型檔案。大檔案建議固定 4KB~8KB 緩衝區(如 new byte[8192]),避免記憶體溢位。
// 錯誤寫法:忽略實際讀取位元組數
while (in.read(buffer) != -1) {
out.write(buffer); // 若最後一次讀取不滿陣列,會寫入舊資料殘留
}
// 正確寫法:捕獲回傳值
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
Java 7+ 建議使用 try-with-resources 自動關閉:
try (FileInputStream in = new FileInputStream(src);
FileOutputStream out = new FileOutputStream(dest)) {
byte[] buffer = new byte[8192];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
} // 自動關閉 in、out
BufferedInputStream/BufferedOutputStream 進一步提升 IO 效能FileChannel.transferTo() 零拷貝技術Files.copy() 提供最簡潔的高階 APIimport java.nio.file.*;
Path source = Paths.get("D:/a.jpg");
Path target = Paths.get("D:/b.jpg");
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);