Java I/O 详解:基础、文件操作与 NIO 实践

Java I/O 详解:基础、文件操作与 NIO 实践

Java I/O (输入输出) 是指用于读取和写入数据的 API,包括从文件、网络和其他数据源进行读取和写入操作。Java 提供了丰富的类和接口来实现各种 I/O 操作,主要包括标准 I/O、文件 I/O 和新 I/O (NIO)。以下是 Java I/O 的详细介绍:

一、基本 I/O

1. 字节流 (Byte Streams)

字节流用于处理原始二进制数据,通常用于处理图片、音频、视频等二进制文件。

  • 输入流 (InputStream) :
    • FileInputStream: 从文件中读取字节流。
    • ByteArrayInputStream: 从字节数组中读取数据。
    • BufferedInputStream: 为其他输入流添加缓冲功能。
  • 输出流 (OutputStream):
    • FileOutputStream: 将字节流写入文件。
    • ByteArrayOutputStream: 将数据写入字节数组。
    • BufferedOutputStream: 为其他输出流添加缓冲功能。
2. 字符流 (Character Streams)

字符流用于处理文本数据,字符流以 16 位 Unicode 字符为单位处理数据。

  • 输入流 (Reader):

    • FileReader: 从文件中读取字符流。
    • StringReader: 从字符串中读取字符数据。
    • BufferedReader: 为其他字符输入流添加缓冲功能,并提供按行读取的功能。
  • 输出流 (Writer):

    • FileWriter: 将字符流写入文件。
    • StringWriter: 将字符数据写入字符串。
    • BufferedWriter: 为其他字符输出流添加缓冲功能。

二、文件 I/O

Java 提供了 File 类用于表示文件和目录,提供了多种方法来操作文件和目录。

  • File 类常用方法 :
    • createNewFile(): 创建一个新的文件。
    • mkdir(), mkdirs(): 创建一个或多个目录。
    • delete(): 删除文件或目录。
    • list(), listFiles(): 列出目录中的文件和子目录。

三、新 I/O (NIO)

NIO (New I/O) 引入了一些高效的 I/O 操作方式,包括缓冲区 (Buffers)、通道 (Channels) 和选择器 (Selectors)。

1. 缓冲区 (Buffers)

缓冲区是一个容器对象,用于特定基本数据类型的元素的线性、有限序列。NIO 缓冲区比传统 I/O 更加高效。

  • 常用缓冲区类型 :
    • ByteBuffer: 存储字节数据。
    • CharBuffer: 存储字符数据。
    • IntBuffer, LongBuffer, DoubleBuffer 等其他基本类型的缓冲区。
2. 通道 (Channels)

通道是用于 I/O 操作的对象,它能够读写数据,但不直接操作数据,而是通过缓冲区来进行操作。

  • 常用通道类型 :
    • FileChannel: 用于文件的读写操作。
    • SocketChannel: 用于 TCP 网络连接的读写操作。
    • DatagramChannel: 用于 UDP 网络连接的读写操作。
3. 选择器 (Selectors)

选择器允许一个线程管理多个通道的 I/O 操作。通过使用选择器,可以在一个单独的线程中管理多个通道,从而提高了效率。

  • 常用方法 :
    • select(): 阻塞直到至少有一个通道准备好了 I/O 操作。
    • selectNow(): 非阻塞地进行选择操作。
    • selectedKeys(): 返回准备好的通道的键集合。

四、文件操作示例

1. 使用 File 类
java 复制代码
import java.io.File;
import java.io.IOException;

public class FileExample {
    public static void main(String[] args) {
        File file = new File("example.txt");

        // 创建文件
        try {
            if (file.createNewFile()) {
                System.out.println("File created: " + file.getName());
            } else {
                System.out.println("File already exists.");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 检查文件是否存在
        if (file.exists()) {
            System.out.println("File exists.");

            // 获取文件信息
            System.out.println("File name: " + file.getName());
            System.out.println("Absolute path: " + file.getAbsolutePath());
            System.out.println("Writeable: " + file.canWrite());
            System.out.println("Readable: " + file.canRead());
            System.out.println("File size in bytes: " + file.length());
        }
    }
}
2. 使用字节流进行文件复制
java 复制代码
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileCopyExample {
    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("source.txt");
             FileOutputStream fos = new FileOutputStream("destination.txt")) {
            int byteContent;
            while ((byteContent = fis.read()) != -1) {
                fos.write(byteContent);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
3. 使用字符流读写文件
java 复制代码
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class FileReadWriteExample {
    public static void main(String[] args) {
        // 写入文件
        try (FileWriter writer = new FileWriter("example.txt")) {
            writer.write("Hello, World!\n");
            writer.write("Java I/O example.");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 读取文件
        try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
4. 使用 NIO 进行文件复制
java 复制代码
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class NIOFileCopyExample {
    public static void main(String[] args) {
        Path sourcePath = Paths.get("source.txt");
        Path destinationPath = Paths.get("destination.txt");

        try {
            Files.copy(sourcePath, destinationPath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

这些示例展示了如何使用 Java I/O 和 NIO 进行文件操作。了解和掌握这些知识点有助于开发高效、可靠的 Java 应用程序。

相关推荐
silvamux_13 分钟前
Spring Boot 调用大模型 api 最小可跑教程
java·spring boot·后端
今年下半年16 分钟前
【Spring Boot 】通过 OpenFeign 请求第三方接口
java·spring boot·后端·openfeign
范什么特西25 分钟前
亲和路由(inspect)
java
她说可以呀28 分钟前
Docker 镜像的两种创建方式
java·分布式·docker
霸道流氓气质37 分钟前
AgentFlow 入门与实战:Task-Based 并发、EWMA 动态调度与四道门禁的 Java 生产级编排
java·开发语言
愿得一猪蹄1 小时前
# Java线程池实战,别再new Thread了
java
ee又momo1 小时前
# 深入理解Java注解,从使用到自定义
java
霸道流氓气质1 小时前
AI智能博客平台实战:RAG增强写作、多Agent协作与语义检索的Vue3 + Spring AI全栈实现
java·人工智能·spring
打工仔折腾 AI2 小时前
LangChain 工具调用实战:从 Tool 定义到 Agent 执行链路拆解
java·前端·人工智能·后端·python·langchain·ai agent 实战
哦虎!2 小时前
【JavaEE】网络原理 - TCP/IP
java