IO 流是 Java 處理數據傳輸的核心。本文系統梳理 File 類常用操作、字節流與字符流區別、InputStream/OutputStream 體系核心方法、緩沖流裝飾模式、文件複製實戰。
File file = new File("E:\\test\\javaIo");
file.isDirectory(); // 是否目錄
file.isFile(); // 是否文件
file.exists(); // 是否存在
file.mkdir(); // 創建單級目錄
file.mkdirs(); // 創建多級目錄
file.createNewFile(); // 創建文件
file.delete(); // 刪除文件/空目錄
file.getAbsolutePath(); // 絕對路徑
file.getName(); // 文件名
file.getParent(); // 父路徑字串
file.getParentFile(); // 父路徑 File 對象
File.separator // 跨平台路徑分隔符
public static void directoryList(File dir) {
if (!dir.exists() || !dir.isDirectory()) throw new IllegalArgumentException();
File[] files = dir.listFiles();
if (files != null) for (File f : files) {
if (f.isDirectory()) directoryList(f);
else System.out.println(f.getName());
}
}
FileFilter filter = f -> f.getName().matches(".*[.]java");
File[] javaFiles = new File("src/day07").listFiles(filter);
public static void delDirectory(File dir) throws IOException {
if (!dir.exists() || !dir.isDirectory()) throw new RuntimeException();
File[] subs = dir.listFiles();
if (subs != null) for (File f : subs) {
if (!f.isDirectory()) { if (!f.delete()) throw new IOException("無法刪除文件"); }
else { delDirectory(f); f.delete(); }
}
dir.delete();
}
| 維度 | 字節流 | 字符流 |
|---|---|---|
| 處理單元 | 1 字節 | 2 字節 Unicode 字符 | 適用數據 | 所有二進制(圖片、視頻、文本) | 僅文本 |
| 操作對象 | 文件本身 | 內存緩沖區 |
| 基類 | InputStream / OutputStream | Reader / Writer |
| flush/close 影響 | 即時見效 | 需 flush/close 才落盤 |
本質:磁盤存儲均為字節,字符流 = 字節流 + 編解碼(Charset)。
abstract int read(); // 讀 1 字節,返回 0-255 或 -1
int read(byte[] b); // 讀入數組,返回實際讀取數
int read(byte[] b, int off, int len); // 指定偏移/長度
long skip(long n); // 跳過 n 字節
int available(); // 可讀字節估算
void close(); // 關閉釋放資源
void mark(int readlimit) / reset(); // 標記/重置(需 markSupported())
// 逐字節讀
InputStream is = new FileInputStream("E:\\javaTest\\1.txt");
int by;
while ((by = is.read()) != -1) System.out.print((char) by);
is.close();
// 批量讀(推薦)
byte[] buf = new byte[1024];
int len;
while ((len = is.read(buf)) != -1) System.out.print(new String(buf, 0, len));
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\\javaTest\\5.txt"));
byte[] buf = new byte[1024];
int len;
while ((len = bis.read(buf)) != -1) System.out.print(new String(buf, 0, len));
bis.close();
abstract void write(int b); // 寫 1 字節(低 8 位)
void write(byte[] b); // 寫整個數組
void write(byte[] b, int off, int len); // 寫部分數組
void flush(); // 強制刷新緩衝區到目標
void close(); // 關閉(含 flush)
OutputStream os = new FileOutputStream("E:\\javaTest\\1.txt"); // 覆蓋模式
// new FileOutputStream("path", true) // 追加模式
os.write("中國".getBytes());
os.flush(); os.close();
// 寫入單字節(ASCII 碼 97 -> 'a')
os.write(97);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:\\javaTest\\5.txt"));
bos.write("中".getBytes());
bos.flush(); bos.close();
InputStream is = new FileInputStream(src);
OutputStream os = new FileInputStream(dest);
byte[] buf = new byte[1024];
int len;
while ((len = is.read(buf)) != -1) os.write(buf, 0, len);
is.close(); os.close();
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dest));
byte[] buf = new byte[1024];
int len;
while ((len = bis.read(buf)) != -1) bos.write(buf, 0, len);
bos.flush(); bos.close(); bis.close();
new String(bytes, StandardCharsets.UTF_8),避免平台默認編碼差異。Files.copy() (NIO.2) 或 FileChannel.transferTo() 零拷貝。