欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > 【Java入门指南 Day13: IO与文件处理】

【Java入门指南 Day13: IO与文件处理】

2025/2/23 15:07:23 来源:https://blog.csdn.net/m0_63887085/article/details/144567482  浏览:    关键词:【Java入门指南 Day13: IO与文件处理】

一、IO流系统概述

Java的IO系统像是一个管道系统,负责数据的输入和输出。可以分为:

  • 字节流:处理二进制数据
  • 字符流:处理文本数据

字节流与字符流对比

// 字节流示例:复制图片
public void copyImage(String source, String target) {try (FileInputStream fis = new FileInputStream(source);FileOutputStream fos = new FileOutputStream(target)) {byte[] buffer = new byte[1024];int length;while ((length = fis.read(buffer)) > 0) {fos.write(buffer, 0, length);}}
}// 字符流示例:读取文本
public void readText(String fileName) {try (FileReader reader = new FileReader(fileName);BufferedReader br = new BufferedReader(reader)) {String line;while ((line = br.readLine()) != null) {System.out.println(line);}}
}

常用流的层次结构

InputStream/OutputStream (字节流)
├── FileInputStream/FileOutputStream
├── BufferedInputStream/BufferedOutputStream
└── DataInputStream/DataOutputStreamReader/Writer (字符流)
├── FileReader/FileWriter
├── BufferedReader/BufferedWriter
└── InputStreamReader/OutputStreamWriter

二、NIO(New IO)系统

NIO提供了非阻塞IO操作的能力,特别适合高并发场景。

Buffer和Channel

public class NIOExample {public void readFile(String fileName) throws IOException {// 创建文件通道try (FileChannel channel = FileChannel.open(Paths.get(fileName), StandardOpenOption.READ)) {// 创建缓冲区ByteBuffer buffer = ByteBuffer.allocate(1024);// 读取数据到缓冲区while (channel.read(buffer) != -1) {buffer.flip();  // 切换到读模式while (buffer.hasRemaining()) {System.out.print((char) buffer.get());}buffer.clear();  // 清空缓冲区}}}
}

非阻塞IO示例

public class NonBlockingServer {public void startServer() throws IOException {// 创建选择器Selector selector = Selector.open();// 配置服务器通道ServerSocketChannel serverChannel = ServerSocketChannel.open();serverChannel.bind(new InetSocketAddress(8080));serverChannel.configureBlocking(false);// 注册接受连接事件serverChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {selector.select();Set<SelectionKey> selectedKeys = selector.selectedKeys();Iterator<SelectionKey> iter = selectedKeys.iterator();while (iter.hasNext()) {SelectionKey key = iter.next();if (key.isAcceptable()) {handleAccept(serverChannel, selector);}iter.remove();}}}
}

三、文件操作最佳实践

文件读写操作

public class FileOperations {// 使用try-with-resources确保资源释放public List<String> readLines(String fileName) {List<String> lines = new ArrayList<>();try (BufferedReader reader = Files.newBufferedReader(Paths.get(fileName), StandardCharsets.UTF_8)) {String line;while ((line = reader.readLine()) != null) {lines.add(line);}}return lines;}// 使用BufferedWriter提高写入性能public void writeLines(String fileName, List<String> lines) {try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(fileName), StandardCharsets.UTF_8)) {for (String line : lines) {writer.write(line);writer.newLine();}}}
}

文件复制与移动

public class FileUtils {// 复制文件public void copyFile(Path source, Path target) throws IOException {// REPLACE_EXISTING:如果目标文件存在则替换// COPY_ATTRIBUTES:复制文件属性Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING,StandardCopyOption.COPY_ATTRIBUTES);}// 移动文件public void moveFile(Path source, Path target) throws IOException {Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);}
}

四、序列化机制

基本序列化

public class SerializationDemo {// 可序列化的类public static class Person implements Serializable {private static final long serialVersionUID = 1L;private String name;private int age;private transient String password;  // 不会被序列化}// 序列化对象public void serialize(Person person, String fileName) {try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(fileName))) {out.writeObject(person);}}// 反序列化对象public Person deserialize(String fileName) {try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName))) {return (Person) in.readObject();}}
}

五、Path与Files工具类使用

Path类操作

public class PathDemo {public void pathOperations() {Path path = Paths.get("/home/user/docs/file.txt");// 获取文件信息System.out.println("文件名: " + path.getFileName());System.out.println("父目录: " + path.getParent());System.out.println("根目录: " + path.getRoot());// 路径操作Path normalizedPath = path.normalize();Path resolvedPath = path.resolve("another.txt");}
}

Files工具类

public class FilesDemo {public void fileOperations() throws IOException {Path path = Paths.get("example.txt");// 创建文件Files.createFile(path);// 写入内容Files.write(path, "Hello, World!".getBytes());// 读取内容byte[] content = Files.readAllBytes(path);// 检查文件属性System.out.println("是否存在: " + Files.exists(path));System.out.println("是否可读: " + Files.isReadable(path));// 遍历目录try (Stream<Path> paths = Files.walk(Paths.get("."))) {paths.forEach(System.out::println);}}
}

最佳实践建议 💡

  1. IO操作
    • 使用缓冲流提高性能
    • 正确关闭资源
    • 使用字符流处理文本
  2. 文件处理
    • 使用Files工具类
    • 处理文件路径用Path
    • 考虑文件编码
  3. 序列化
    • 定义serialVersionUID
    • 敏感数据用transient
    • 考虑安全性

常见陷阱提醒 ⚠️

  1. 资源泄露
// 错误:未正确关闭资源
FileInputStream fis = new FileInputStream("file.txt");
// 使用文件...
fis.close();  // 可能永远不会执行// 正确:使用try-with-resources
try (FileInputStream fis = new FileInputStream("file.txt")) {// 使用文件...
}
  1. 编码问题
// 错误:未指定字符编码
FileReader reader = new FileReader("file.txt");// 正确:指定字符编码
Reader reader = new InputStreamReader(new FileInputStream("file.txt"), StandardCharsets.UTF_8);
  1. 性能问题
// 低效:逐字节读取
int b;
while ((b = inputStream.read()) != -1) {// 处理字节...
}// 高效:使用缓冲区
byte[] buffer = new byte[8192];
int length;
while ((length = inputStream.read(buffer)) != -1) {// 处理缓冲区...
}

IO和文件处理是Java应用程序的基础功能。掌握这些知识对于开发高质量的应用程序至关重要。记住要注意资源管理、性能优化和错误处理。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词