JavaEE 初阶文件操作与 IO 详解

发布于:2025-05-22 ⋅ 阅读:(21) ⋅ 点赞:(0)
一、文件操作基础:File 类

作用:操作文件或目录(创建、删除、获取信息)。
核心方法

  • exists():文件是否存在
  • createNewFile():创建新文件
  • mkdir():创建目录
  • delete():删除文件或目录

代码示例

import java.io.File;
import java.io.IOException;

public class FileCreateDemo {
    public static void main(String[] args) {
        // 1. 创建文件对象(不实际创建文件)
        File file = new File("test.txt");
        
        try {
            // 2. 创建文件(需处理 IOException)
            if (file.createNewFile()) {
                System.out.println("文件创建成功");
            } else {
                System.out.println("文件已存在");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 3. 创建目录(单层)
        File dir = new File("mydir");
        if (dir.mkdir()) {
            System.out.println("目录创建成功");
        }

        // 4. 创建多级目录
        File multiDir = new File("parent/child");
        if (multiDir.mkdirs()) {
            System.out.println("多级目录创建成功");
        }
    }
}

重点

  • new File("路径") 只是创建对象,不会实际创建文件。
  • 操作可能抛出 IOException,必须处理异常。
  • createNewFile():原子性操作,文件不存在时创建并返回 true
  • mkdir() 与 mkdirs():后者可创建多级目录
  • 路径分隔符:Windows 用 \(需转义为 \\),Linux/Mac 用 /

2. 删除与判断文件属性

public class FileDeleteDemo {
    public static void main(String[] args) {
        File file = new File("test.txt");
        
        // 1. 删除文件(立刻删除,非移到回收站)
        if (file.delete()) {
            System.out.println("文件删除成功");
        }

        // 2. 判断文件属性
        System.out.println("是否隐藏文件: " + file.isHidden());
        System.out.println("是否可读: " + file.canRead());
        System.out.println("最后修改时间: " + file.lastModified());
    }
}
二、IO 流分类与核心类
1. 按方向分
  • 输入流:从文件/网络读取数据 → InputStreamReader
  • 输出流:向文件/网络写入数据 → OutputStreamWriter
2. 按数据类型分

类型 字节流(二进制) 字符流(文本)
输入 InputStream Reader
输出 OutputStream Writer

为什么需要字符流
直接处理文本更方便,自动处理字符编码(如 UTF-8)。

三、字节流实战:文件复制

代码示例

import java.io.*;

public class FileCopy {
    public static void main(String[] args) {
        // 1. 定义输入输出文件
        File srcFile = new File("source.jpg");
        File destFile = new File("copy.jpg");

        // 2. 使用 try-with-resources 自动关闭流
        try (InputStream is = new FileInputStream(srcFile);
             OutputStream os = new FileOutputStream(destFile)) {
            
            // 3. 缓冲区提高效率
            byte[] buffer = new byte[1024];
            int len;
            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len); // 写入实际读取的字节数
            }
            System.out.println("文件复制完成");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

重点

  • try-with-resources 自动关闭流,避免资源泄漏。
  • 缓冲区大小(如 1024)影响性能,通常设为 4KB~8KB。
  • read() 返回实际读取字节数,避免写入多余数据。
  • 逐字节读写效率极低,需优化为缓冲区读写。
四、字符流实战:读写文本文件

代码示例(处理中文不乱码)

import java.io.*;

public class TextFileDemo {
    public static void main(String[] args) {
        // 写入文件(UTF-8编码)
        try (Writer writer = new FileWriter("data.txt", StandardCharsets.UTF_8)) {
            writer.write("你好,JavaEE!\n");
            writer.write("Hello, World!");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 读取文件
        try (Reader reader = new FileReader("data.txt", StandardCharsets.UTF_8);
             BufferedReader br = new BufferedReader(reader)) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

重点

  • FileWriter/FileReader 默认使用系统编码,建议显式指定(如 UTF-8)。
  • BufferedReader 提升读取效率,readLine() 逐行读取。
    五、缓冲流:性能优化利器

    代码示例

  • public class BufferedByteStreamDemo {
        public static void main(String[] args) {
            try (InputStream is = new FileInputStream("source.jpg");
                 BufferedInputStream bis = new BufferedInputStream(is); // 添加缓冲
                 OutputStream os = new FileOutputStream("copy.jpg");
                 BufferedOutputStream bos = new BufferedOutputStream(os)) {
                
                byte[] buffer = new byte[8192]; // 8KB 缓冲区
                int len;
                while ((len = bis.read(buffer)) != -1) {
                    bos.write(buffer, 0, len); // 写入实际读取的字节数
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    重点

  • 缓冲流(BufferedXXX)通过减少物理 IO 次数提升性能。
  • 默认缓冲区大小 8KB,可根据需求调整。
  • 冲区大小通常设为 4096(4KB)~ 8192(8KB)
  • BufferedInputStream 内部维护 8KB 缓冲区,减少物理磁盘访问次数
六、NIO 新特性:更简洁的文件操作

Java NIO(New IO)核心类

  • Path:替代 File 类,路径操作更灵活
  • Files:提供静态方法简化文件操作

代码示例

import java.nio.file.*;

public class NioDemo {
    public static void main(String[] args) {
        Path source = Paths.get("source.txt");
        Path target = Paths.get("backup.txt");

        try {
            // 复制文件(自动覆盖)
            Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);

            // 读取所有行(UTF-8)
            List<String> lines = Files.readAllLines(source);
            lines.forEach(System.out::println);

            // 写入文件
            Files.write(target, "新内容".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

重点

  • Files.copy() 比传统 IO 更简洁。
  • readAllLines() 适合小文件,大文件仍需流式读取。
七、高级应用场景

1. 文件监控(WatchService)

public class FileWatcherDemo {
    public static void main(String[] args) throws IOException {
        WatchService watchService = FileSystems.getDefault().newWatchService();
        Path dir = Paths.get("."); // 监控当前目录

        dir.register(watchService, 
            StandardWatchEventKinds.ENTRY_CREATE,
            StandardWatchEventKinds.ENTRY_DELETE,
            StandardWatchEventKinds.ENTRY_MODIFY);

        while (true) {
            WatchKey key = watchService.take(); // 阻塞直到事件发生
            for (WatchEvent<?> event : key.pollEvents()) {
                System.out.println("事件类型: " + event.kind());
                System.out.println("文件: " + event.context());
            }
            key.reset(); // 重置监听
        }
    }
}

2. 大文件逐行处理(内存优化)

public class LargeFileProcessor {
    public static void main(String[] args) {
        try (Stream<String> lines = Files.lines(Paths.get("bigdata.txt"))) {
            lines.filter(line -> line.contains("error"))
                 .forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
八、核心总结
  1. 选择流类型
    • 文本文件 → 字符流(Reader/Writer)
    • 图片/视频 → 字节流(InputStream/OutputStream)
  2. 性能优化
    • 使用缓冲流(BufferedXXX)
    • 合理设置缓冲区大小
  3. 资源管理
    • 必须用 try-with-resources 或手动关闭流
  4. NIO 优势
    • 更简洁的 API
    • 支持异步和非阻塞 IO(高级特性)

网站公告

今日签到

点亮在社区的每一天
去签到