序列流SequenceInputStream将三个文件信息合并至一个文件中

该博客演示了如何使用Java的SequenceInputStream类将多个文件内容合并到一个文件中,涉及Vector和ArrayList容器,以及不同方式获取容器元素。最终将所有文件内容写入到‘总文件.txt’。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package demo.io;

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

/**
 * 将三个文件信息合并至一个文件中
 */
class 序列流SequenceInputStream {
    public static void main(String[] args) {
        Vector<FileInputStream> fileVec = new Vector<>();//方法1
        ArrayList<FileInputStream> fileArr = new ArrayList<>();//方法2
        try {
            //方法1 使用Vector容器插入需要合并的文件路径
            fileVec.add(new FileInputStream("后期设备的配置文件.properties"));
            fileVec.add(new FileInputStream("系统信息日志.txt"));
            fileVec.add(new FileInputStream("异常日志.txt"));
            //方法2 使用ArrayList容器插入需要合并的文件路径
            fileArr.add(new FileInputStream("后期设备的配置文件.properties"));
            fileArr.add(new FileInputStream("系统信息日志.txt"));
            fileArr.add(new FileInputStream("异常日志.txt"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        //方法1 利用枚举获得Vector中元素
        Enumeration<FileInputStream> en1 = fileVec.elements();

        //方法2 利用迭代器获得ArrayList中元素
        final Iterator<FileInputStream> it = fileArr.iterator();
        //枚举内部类
        Enumeration<FileInputStream> en2 = new Enumeration<FileInputStream>() {
            @Override
            public boolean hasMoreElements() {
                return it.hasNext();//内部类访问外部类元素需要加final关键字
            }

            @Override
            public FileInputStream nextElement() {
                return it.next();
            }
        };

        //方法3   方法3的原理就是方法2
        Enumeration<FileInputStream> en3 = Collections.enumeration(fileArr);

        //方法4   用于两个流合并
        try {
            SequenceInputStream sis2 = new SequenceInputStream(new FileInputStream("1.txt"), new FileInputStream("2.txt"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        //使用序列流接受这些元素
        SequenceInputStream sis = new SequenceInputStream(en3);
        int len = 0;
        byte[] buf = new byte[1024];
        PrintWriter pw = null;
        try {
            //写入总文件,并开启自动刷新
            pw = new PrintWriter(new FileWriter("总文件.txt"), true);
            while ((len = sis.read(buf)) != -1) {
                pw.print(new String(buf, 0, len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (pw != null) {
                pw.close();
            }
            try {
                sis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

<think>我们参考了关于Java IO流的多个引用资料,现在需要回答用户的问题:Java中IO流的分类有哪些? 根据引用资料,我们可以从多个角度对IO流进行分类: 1. 按数据流向分类(以内存为参照): - 输入流(Input Stream):将数据从数据源(如文件)读取到内存中。 - 输出流(Output Stream):将数据从内存写入到数据目的地(如文件)。 2. 按操作数据单位分类: - 字节流:以8位字节(1 byte)为单位进行读写操作。可以处理所有类型的数据(包括文本、图片、音频、视频等)。 - 字符流:以16位字符(2 bytes)为单位进行读写操作。主要用于处理文本数据,能够处理字符编码问题。 3. 按流的角色分类: - 节点流:直接从数据源或目的地读写数据的流,也称为低级流。 - 处理流:对已存在的流(节点流或处理流)进行封装,提供更强大的读写功能(如缓冲、转换等),也称为高级流。 此外,引用中还提到Java IO流体系中有4个抽象基类,它们分别是: - 字节输入流:`InputStream` - 字节输出流:`OutputStream` - 字符输入流:`Reader` - 字符输出流:`Writer` Java的IO流体系中的40多个类都是从这4个抽象基类派生出来的,并且子类的名称都是以父类名作为后缀(例如`FileInputStream`、`FileReader`等)。 下面我们详细展开每个分类: ### 1. 按数据流向分类 - **输入流**:用于从数据源读取数据。常见的输入流有: - `InputStream`(字节输入流基类) - `Reader`(字符输入流基类) - 具体实现类:`FileInputStream`、`FileReader`等。 - **输出流**:用于向目标写入数据。常见的输出流有: - `OutputStream`(字节输出流基类) - `Writer`(字符输出流基类) - 具体实现类:`FileOutputStream`、`FileWriter`等。 ### 2. 按操作数据单位分类 - **字节流**:用于处理二进制数据,如图片、音频、视频等。字节流的基本单位是字节(8 bits)。主要的抽象基类有: - `InputStream`(字节输入流) - `OutputStream`(字节输出流) - **字符流**:用于处理文本数据,字符流的基本单位是字符(16 bits)。字符流在读写时会自动处理字符编码(如UTF-8、GBK等)。主要的抽象基类有: - `Reader`(字符输入流) - `Writer`(字符输出流) 注意:字符流实际上是在字节流的基础上,通过`InputStreamReader`和`OutputStreamWriter`(属于处理流)将字节流转换为字符流,并指定字符编码。 ### 3. 按流的角色分类 - **节点流**:直接连接到数据源或目的地,负责直接读写数据。例如: - 文件流:`FileInputStream`、`FileOutputStream`、`FileReader`、`FileWriter` - 数组流:`ByteArrayInputStream`、`ByteArrayOutputStream`、`CharArrayReader`、`CharArrayWriter` - 管道流:`PipedInputStream`、`PipedOutputStream`、`PipedReader`、`PipedWriter` - **处理流**:对节点流或其他处理流进行包装,提供更便捷或更高效的功能。例如: - 缓冲流:`BufferedInputStream`、`BufferedOutputStream`、`BufferedReader`、`BufferedWriter`(提供缓冲功能,减少I/O次数) - 转换流:`InputStreamReader`(将字节输入流转换为字符输入流)、`OutputStreamWriter`(将字节输出流转换为字符输出流) - 数据流:`DataInputStream`、`DataOutputStream`(用于读写基本数据类型和字符串) - 对象流:`ObjectInputStream`、`ObjectOutputStream`(用于对象的序列化和反序列化) - 打印流:`PrintStream`、`PrintWriter`(提供方便的打印方法) - 合并流:`SequenceInputStream`(将多个输入流合并一个输入流) ### 总结 Java中的IO流分类可以归纳为三个维度: 1. **流向**:输入流 vs 输出流 2. **数据单位**:字节流 vs 字符流 3. **角色**:节点流 vs 处理流 整个Java IO流体系都是建立在四个抽象基类(`InputStream`、`OutputStream`、`Reader`、`Writer`)之上的,通过组合和扩展这些基类,形成了丰富的IO流类库。 下面是一个简单的类图关系(使用mermaid语法): ```mermaid classDiagram direction BT class InputStream class OutputStream class Reader class Writer class FileInputStream FileInputStream --|> InputStream class FileOutputStream FileOutputStream --|> OutputStream class FileReader FileReader --|> Reader class FileWriter FileWriter --|> Writer class BufferedInputStream BufferedInputStream --|> FilterInputStream FilterInputStream --|> InputStream class BufferedReader BufferedReader --|> Reader class InputStreamReader InputStreamReader --|> Reader ``` 注意:`FilterInputStream`是处理流的基类,它包装了另一个输入流(节点流或其他处理流)。 ### 示例代码 下面是一个使用字节流和字符流读取文件的简单示例: **字节流读取文件(适合二进制文件)**: ```java try (InputStream in = new FileInputStream("test.jpg")) { int data; while ((data = in.read()) != -1) { // 处理每个字节 } } catch (IOException e) { e.printStackTrace(); } ``` **字符流读取文件(适合文本文件)**: ```java try (Reader reader = new FileReader("test.txt")) { int data; while ((data = reader.read()) != -1) { char ch = (char) data; // 处理每个字符 } } catch (IOException e) { e.printStackTrace(); } ``` **使用缓冲流提高效率(处理流)**: ```java try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) { String line; while ((line = br.readLine()) != null) { // 处理一行文本 } } catch (IOException e) { e.printStackTrace(); } ``` 通过以上分类和示例,我们可以清晰地了解Java IO流的分类体系。 §§相关问题§§ 1. 字节流和字符流在什么场景下使用? 2. 处理流(如缓冲流)是如何提高IO效率的? 3. Java IO流中哪些流是节点流?哪些是处理流? 4. 如何选择使用字节流还是字符流?</think>### Java IO 流分类详解 根据引用资料,Java IO 流体系主要从三个维度进行分类: #### 1. **按数据流向分类**(以内存为参照) | 类型 | 功能描述 | 核心抽象类 | 典型实现类 | |------------|----------------------------------|----------------|------------------------| | **输入流** | 将数据从外部源读取到内存 | `InputStream` | `FileInputStream` | | | | `Reader` | `FileReader` | | **输出流** | 将数据从内存写入到外部目标 | `OutputStream` | `FileOutputStream` | | | | `Writer` | `FileWriter` | #### 2. **按操作数据单位分类** | 类型 | 单位 | 适用场景 | 抽象基类 | 特点 | |------------|--------|-----------------------------|----------------|-----------------------| | **字节流** | 8 bit | 处理二进制文件(图片/视频等) | `InputStream` | 后缀为`Stream` | | | | | `OutputStream` | 如`FileInputStream` | | **字符流** | 16 bit | 处理文本文件 | `Reader` | 后缀为`Reader`/`Writer` | | | | | `Writer` | 如`FileReader` | #### 3. **按流的角色分类** | 类型 | 功能描述 | 特点 | 典型实现类 | |--------------|----------------------------------|--------------------------|------------------------| | **节点流** | 直接连接数据源/目的地 | 基础IO操作 | `FileInputStream` | | | | | `ByteArrayInputStream` | | **处理流** | 包装节点流,增强功能 | 提供高级功能 | `BufferedReader` | | (包装流) | | 需传入节点流作为参数 | `ObjectInputStream` | #### 完整分类体系图示 ```mermaid graph TD A[Java IO流] --> B[按流向] A --> C[按数据单位] A --> D[按角色] B --> B1[输入流] B --> B2[输出流] C --> C1[字节流] C --> C2[字符流] D --> D1[节点流] D --> D2[处理流] B1 --> C1 B1 --> C2 B2 --> C1 B2 --> C2 D1 --> F[FileInputStream等] D2 --> G[BufferedReader等] ``` #### 关键特性对比 1. **抽象基类关系**: - 所有字节流均派生自`InputStream`/`OutputStream` - 所有字符流均派生自`Reader`/`Writer` - 子类命名规则:父类名作为后缀(如`FileInputStream`)[^1][^2] 2. **处理流工作原理**: ```java // 典型处理流使用示例 try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) { String line; while ((line = br.readLine()) != null) { // 增强的读取功能 System.out.println(line); } } ``` - 处理流通过包装节点流实现功能扩展(如缓冲、数据类型转换等) 3. **字符流本质**: - 底层通过`InputStreamReader`/`OutputStreamWriter`将字节流转换为字符流 - 自动处理字符编码(如UTF-8、GBK等)[^2][^4] #### 典型应用场景 | 场景 | 推荐流类型 | 原因 | |---------------------|------------------------|--------------------------| | 图片/视频传输 | 字节流(如`FileInputStream`) | 保持二进制数据完整性 | | 文本文件读取 | 字符流(如`BufferedReader`) | 自动处理编码,支持按行读 | | 对象序列化 | 处理流(`ObjectInputStream`) | 可直接读写Java对象 | | 内存数据操作 | 字节数组流(`ByteArrayInputStream`) | 无需物理文件 | ### 总结 Java IO流通过**流向**(输入/输出)、**数据单位**(字节/字符)、**角色**(节点流/处理流)三个维度构建了完整的IO体系。40多个IO类均派生自4个抽象基类(`InputStream`, `OutputStream`, `Reader`, `Writer`),这种设计提供了高度灵活性和扩展性[^1][^2][^3]。 --- ### 相关问题 1. **字节流和字符流在读取文本文件时有何性能差异?** 2. **为什么处理流需要包装节点流才能工作?** 3. **如何选择合适的缓冲流提高IO效率?** 4. **Java NIO与传统IO流的主要区别是什么?** [^1]: IO流的分类。按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)... [^2]: Java IO流分类。按操作数据单位不同分为:字节流(8bit)如二进制文件;字符流,如文本文件... [^3]: java中的IO:流的分类。输入流进行读操作,输出流进行写操作... [^4]: Java IO流的分类。这些类如果是以Stream单词结尾就是字节流, 如果是以Reader结尾就是字符输入流...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值