首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java 檔案操作完整指南:IO 流、Reader/Writer、常用工具類

     編輯:Java 程式設計入門

Java 檔案操作核心在於 java.io 套件提供的位元組流(InputStream/OutputStream)與字元流(Reader/Writer)體系。本文系統整理常用類別、方法與最佳實務,並提供一個功能完整的檔案工具類原始碼。

核心類別體系

類別類型用途常見子類別
InputStream抽象類別位元組輸入(二進位資料)FileInputStream, ByteArrayInputStream, BufferedInputStream
OutputStream抽象類別位元組輸出FileOutputStream, ByteArrayOutputStream, BufferedOutputStream
Reader抽象類別字元輸入(文字資料,Unicode)FileReader, BufferedReader, InputStreamReader
Writer抽象類別字元輸出FileWriter, BufferedWriter, OutputStreamWriter, PrintWriter
File實體類別檔案/目錄路徑操作(不處理內容)—
RandomAccessFile實體類別隨機存取(可讀寫、可定位指標)—

關鍵方法速查

  • InputStream.read():讀取單一位元組,回傳 int (0-255),結束回傳 -1。
  • InputStream.read(byte[] b):讀入位元組陣列,回傳實際讀取數。
  • Reader.read(char[] cbuf):讀入字元陣列。
  • BufferedReader.readLine():按行讀取文字,不含換行符,結束回傳 null。
  • PrintWriter.println():輸出字串並自動換行、刷新緩衝區。
  • File.listFiles():列出目錄下所有檔案與子目錄(回傳 File[])。
  • File.mkdir() / mkdirs():建立單層/多層目錄。
  • File.createNewFile():建立新檔案(原子操作)。
  • File.delete():刪除檔案或空目錄。

完整檔案工具類

package mytestfiles;

import java.io.*;
import java.util.Arrays;

public class FilesUtil {

    /** 寫入字串陣列,每行一筆 */
    public void writeLines(String dir, String fileName, String[] lines) throws IOException {
        File f = new File(dir, fileName);
        try (FileWriter fw = new FileWriter(f);
             PrintWriter pw = new PrintWriter(fw)) {
            for (String line : lines) {
                pw.println(line);
            }
        }
    }

    /** 寫入單一字串 */
    public void writeString(String dir, String fileName, String content) throws IOException {
        File f = new File(dir, fileName);
        try (FileWriter fw = new FileWriter(f)) {
            fw.write(content);
        }
    }

    /** 建立或刪除檔案 */
    public boolean createOrDeleteFile(String dir, String fileName) throws IOException {
        File f = new File(dir, fileName);
        if (f.exists()) {
            return f.delete();
        } else {
            return f.createNewFile();
        }
    }

    /** 建立或刪除目錄 */
    public boolean createOrDeleteDir(String dir, String dirName) {
        File f = new File(dir, dirName);
        try {
            if (f.exists()) {
                return deleteDirectory(f); // 遞迴刪除非空目錄
            } else {
                return f.mkdirs();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    private boolean deleteDirectory(File dir) {
        File[] files = dir.listFiles();
        if (files != null) {
            for (File f : files) {
                if (f.isDirectory()) deleteDirectory(f);
                else f.delete();
            }
        }
        return dir.delete();
    }

    /** 列出目錄內容 */
    public void listDirectory(String dirPath) {
        File dir = new File(dirPath);
        File[] files = dir.listFiles();
        if (files == null) return;
        for (File f : files) {
            System.out.println((f.isDirectory() ? "[DIR]  " : "[FILE] ") + f.getName());
        }
    }

    /** 檢查檔案是否為空 */
    public boolean isFileEmpty(String dir, String fileName) throws IOException {
        File f = new File(dir, fileName);
        try (FileReader fr = new FileReader(f)) {
            return fr.read() == -1;
        }
    }

    /** 讀取整個檔案內容(小檔案適用) */
    public String readAll(String dir, String fileName) throws IOException {
        File f = new File(dir, fileName);
        StringBuilder sb = new StringBuilder();
        try (FileReader fr = new FileReader(f);
             BufferedReader br = new BufferedReader(fr)) {
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line).append(System.lineSeparator());
            }
        }
        return sb.toString();
    }

    /** 逐行讀取並處理(大檔案適用) */
    public void processLines(String dir, String fileName, LineProcessor processor) throws IOException {
        File f = new File(dir, fileName);
        try (FileReader fr = new FileReader(f);
             BufferedReader br = new BufferedReader(fr)) {
            String line;
            while ((line = br.readLine()) != null) {
                processor.process(line);
            }
        }
    }

    @FunctionalInterface
    public interface LineProcessor {
        void process(String line);
    }

    // 測試主程式
    public static void main(String[] args) throws IOException {
        FilesUtil util = new FilesUtil();
        String base = "f:/test_io/";
        util.createOrDeleteDir(base, "demo");
        
        String[] data = new String[50];
        Arrays.setAll(data, i -> "資料行 " + i);
        util.writeLines(base + "demo/", "data.txt", data);
        
        System.out.println("=== 逐行處理 ===");
        util.processLines(base + "demo/", "data.txt", line -> System.out.println(line));
    }
}

最佳實務總結

  1. 優先使用字元流處理文字:FileReader/Writer 或 BufferedReader/Writer,自動處理編碼。
  2. 大檔案必須串流處理:避免 readAllBytes() 或一次讀入記憶體,使用 BufferedReader.readLine() 或 InputStream.read(byte[]) 迴圈。
  3. 一定要關閉資源:Java 7+ 請使用 try-with-resources 語法,確保 close() 被呼叫。
  4. 指定編碼:建議明確使用 StandardCharsets.UTF_8 搭配 InputStreamReader/OutputStreamWriter,避免平台預設編碼差異。
  5. 路徑處理:Java 7+ 建議改用 java.nio.file.Path、Files、Paths API,功能更強大(複製、移動、屬性讀取、走訪目錄樹)。

NIO.2 現代化替代方案

import java.nio.file.*;
import java.io.IOException;
import java.util.stream.Stream;

public class ModernFileOps {
    public static void main(String[] args) throws IOException {
        Path dir = Paths.get("f:/test_io/demo");
        Files.createDirectories(dir);
        
        // 寫入
        Files.write(dir.resolve("data.txt"), 
            Arrays.asList("Line 1", "Line 2"), 
            StandardCharsets.UTF_8, StandardOpenOption.CREATE);
        
        // 逐行串流讀取 (自動關閉)
        try (Stream lines = Files.lines(dir.resolve("data.txt"))) {
            lines.forEach(System.out::println);
        }
        
        // 走訪目錄樹
        Files.walkFileTree(dir, new SimpleFileVisitor() {
            @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
                System.out.println(file);
                return FileVisitResult.CONTINUE;
            }
        });
    }
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved