Java I/O完整教程:字节流字符流操作与实战代码示例

2024-06-21 李腾 98 次阅读 0 次点赞
本教程全面解析Java I/O包的核心功能,涵盖字节流(FileInputStream、BufferedInputStream)、字符流(FileReader、BufferedReader)和文件操作类(File、RandomAccessFile)的详细使用方法。通过丰富的代码示例展示文件创建、读写操作、数据流处理和目录管理,并提供try-with-resources资源管理、缓冲流性能优化等实用建议,帮助开发者高效处理各种I/O场景。

Java I/O(java.io)包提供了用于处理输入输出的类和接口,是Java标准库中用于文件操作和数据流处理的核心部分。

主要组件

1. 字节流

1、InputStream/OutputStream: 处理字节数据的抽象基类

2、FileInputStream/FileOutputStream: 文件字节流

3、BufferedInputStream/BufferedOutputStream: 缓冲字节流

4、DataInputStream/DataOutputStream: 处理基本数据类型的字节流

2. 字符流

1、Reader/Writer: 处理字符数据的抽象基类

2、FileReader/FileWriter: 文件字符流

3、BufferedReader/BufferedWriter: 缓冲字符流

3. 其他重要类

1、File: 文件和目录路径名的抽象表示

2、RandomAccessFile: 随机访问文件

示例代码

1. 文件读写示例

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class JavaIOExamples {
    
    // 使用File类操作文件和目录
    public static void fileOperations() {
        try {
            File file = new File("example.txt");
            
            // 创建文件
            if (file.createNewFile()) {
                System.out.println("文件创建成功: " + file.getName());
            } else {
                System.out.println("文件已存在");
            }
            
            // 获取文件信息
            System.out.println("文件名: " + file.getName());
            System.out.println("绝对路径: " + file.getAbsolutePath());
            System.out.println("可写: " + file.canWrite());
            System.out.println("可读: " + file.canRead());
            System.out.println("文件大小: " + file.length() + " bytes");
            
        } catch (IOException e) {
            System.out.println("发生错误");
            e.printStackTrace();
        }
    }
    
    // 使用FileWriter写入文件
    public static void writeWithFileWriter() {
        try (FileWriter writer = new FileWriter("output.txt")) {
            writer.write("Hello, Java IO!\n");
            writer.write("这是使用FileWriter写入的文本\n");
            writer.write("当前时间: " + new java.util.Date());
            System.out.println("文件写入成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // 使用FileReader读取文件
    public static void readWithFileReader() {
        try (FileReader reader = new FileReader("output.txt")) {
            int character;
            System.out.println("使用FileReader读取文件内容:");
            while ((character = reader.read()) != -1) {
                System.out.print((char) character);
            }
            System.out.println();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // 使用BufferedReader高效读取文件
    public static void readWithBufferedReader() {
        try (BufferedReader reader = new BufferedReader(new FileReader("output.txt"))) {
            String line;
            System.out.println("使用BufferedReader读取文件内容:");
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // 使用BufferedWriter高效写入文件
    public static void writeWithBufferedWriter() {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter("buffered_output.txt"))) {
            writer.write("第一行内容");
            writer.newLine();
            writer.write("第二行内容");
            writer.newLine();
            writer.write("使用BufferedWriter写入更高效");
            System.out.println("BufferedWriter写入完成");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // 使用FileInputStream读取二进制文件
    public static void readWithFileInputStream() {
        try (FileInputStream input = new FileInputStream("output.txt")) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            System.out.println("使用FileInputStream读取字节:");
            while ((bytesRead = input.read(buffer)) != -1) {
                System.out.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // 使用FileOutputStream写入二进制数据
    public static void writeWithFileOutputStream() {
        try (FileOutputStream output = new FileOutputStream("binary_output.dat")) {
            String text = "这是二进制文件内容";
            byte[] bytes = text.getBytes();
            output.write(bytes);
            System.out.println("二进制文件写入完成");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // 使用DataOutputStream写入基本数据类型
    public static void writeWithDataStream() {
        try (DataOutputStream dos = new DataOutputStream(new FileOutputStream("data_output.dat"))) {
            dos.writeInt(12345);
            dos.writeDouble(3.14159);
            dos.writeBoolean(true);
            dos.writeUTF("Hello DataStream");
            System.out.println("基本数据类型写入完成");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // 使用DataInputStream读取基本数据类型
    public static void readWithDataStream() {
        try (DataInputStream dis = new DataInputStream(new FileInputStream("data_output.dat"))) {
            int intValue = dis.readInt();
            double doubleValue = dis.readDouble();
            boolean booleanValue = dis.readBoolean();
            String stringValue = dis.readUTF();
            
            System.out.println("读取的基本数据类型:");
            System.out.println("整数: " + intValue);
            System.out.println("浮点数: " + doubleValue);
            System.out.println("布尔值: " + booleanValue);
            System.out.println("字符串: " + stringValue);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // 文件复制功能
    public static void copyFile(String sourcePath, String destPath) {
        try (FileInputStream fis = new FileInputStream(sourcePath);
             FileOutputStream fos = new FileOutputStream(destPath)) {
            
            byte[] buffer = new byte[1024];
            int length;
            while ((length = fis.read(buffer)) > 0) {
                fos.write(buffer, 0, length);
            }
            System.out.println("文件复制完成: " + sourcePath + " -> " + destPath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // 读取文件到列表
    public static List<String> readFileToList(String filename) {
        List<String> lines = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
            String line;
            while ((line = reader.readLine()) != null) {
                lines.add(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return lines;
    }
    
    public static void main(String[] args) {
        System.out.println("=== Java I/O 示例 ===\n");
        
        // 文件操作
        fileOperations();
        System.out.println();
        
        // 字符流示例
        writeWithFileWriter();
        readWithFileReader();
        System.out.println();
        
        // 缓冲流示例
        writeWithBufferedWriter();
        readWithBufferedReader();
        System.out.println();
        
        // 字节流示例
        readWithFileInputStream();
        writeWithFileOutputStream();
        System.out.println();
        
        // 数据流示例
        writeWithDataStream();
        readWithDataStream();
        System.out.println();
        
        // 文件复制
        copyFile("output.txt", "copy_output.txt");
        System.out.println();
        
        // 读取文件到列表
        List<String> fileContent = readFileToList("output.txt");
        System.out.println("文件内容行数: " + fileContent.size());
        for (String line : fileContent) {
            System.out.println("行: " + line);
        }
    }
}

2. 目录操作示例

import java.io.File;
import java.io.FilenameFilter;

public class DirectoryOperations {
    
    // 列出目录内容
    public static void listDirectory(String path) {
        File directory = new File(path);
        
        if (!directory.exists()) {
            System.out.println("目录不存在: " + path);
            return;
        }
        
        if (!directory.isDirectory()) {
            System.out.println("路径不是目录: " + path);
            return;
        }
        
        System.out.println("目录内容: " + path);
        String[] files = directory.list();
        if (files != null) {
            for (String file : files) {
                System.out.println("  " + file);
            }
        }
    }
    
    // 使用过滤器列出特定文件
    public static void listFilesWithFilter(String path, final String extension) {
        File directory = new File(path);
        
        FilenameFilter filter = new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.toLowerCase().endsWith(extension);
            }
        };
        
        String[] files = directory.list(filter);
        if (files != null) {
            System.out.println(extension + " 文件:");
            for (String file : files) {
                System.out.println("  " + file);
            }
        }
    }
    
    // 创建目录结构
    public static void createDirectoryStructure() {
        File dir1 = new File("test_dir");
        File dir2 = new File("test_dir/sub_dir");
        File file = new File("test_dir/example.txt");
        
        // 创建目录
        if (dir1.mkdir()) {
            System.out.println("目录创建成功: " + dir1.getPath());
        }
        
        // 创建多级目录
        if (dir2.mkdirs()) {
            System.out.println("多级目录创建成功: " + dir2.getPath());
        }
        
        // 创建文件
        try {
            if (file.createNewFile()) {
                System.out.println("文件创建成功: " + file.getPath());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
        System.out.println("=== 目录操作示例 ===\n");
        
        // 列出当前目录
        listDirectory(".");
        System.out.println();
        
        // 使用过滤器列出Java文件
        listFilesWithFilter(".", ".java");
        System.out.println();
        
        // 创建目录结构
        createDirectoryStructure();
    }
}

重要特点

1、流的概念: Java I/O 基于流的概念,数据像水流一样流动

2、字节流 vs 字符流:

3、 字节流处理二进制数据

4、 字符流处理文本数据,支持字符编码

5、装饰器模式: 通过组合不同的流类来增强功能

6、资源管理: 使用 try-with-resources 自动关闭流

使用建议

1、对于文本文件,优先使用字符流(Reader/Writer)

2、对于二进制文件,使用字节流(InputStream/OutputStream)

3、使用缓冲流提高I/O性能

4、始终使用 try-with-resources 确保流正确关闭

5、注意字符编码问题,特别是在处理多语言文本时

这些示例展示了Java I/O包的基本用法,涵盖了文件操作、目录管理和不同类型的数据流处理。

最后更新于3月前
本文由人工编写,AI优化,转载请注明原文地址: Java I/O使用指南:文件读写与流操作详解及代码实例

评论 (1)

发表评论

昵称:加载中...
林小雅2025-11-09 20:37:11
最近正好在做一个日志分析的小工具,用到了BufferedReader来读取大文件,配合流式处理确实比一次性加载高效多了。感谢作者分享这么详细的示例!