Java SequenceInputStream 类
最后修改时间:2025 年 4 月 16 日
java.io.SequenceInputStream
类将多个输入流连接成一个连续的流。 它按顺序从每个输入流中读取数据,直到到达结尾,然后自动切换到下一个输入流。这对于组合多个数据源非常有用。
SequenceInputStream
扩展了 InputStream
并提供了顺序读取功能。 它支持枚举流或一对流。 当到达当前流的 EOF 时,该类会自动处理流切换。
SequenceInputStream 类概述
SequenceInputStream
提供从多个流的顺序读取。 主要方法包括标准的 InputStream 操作,如 read、skip 和 close。 该类管理当前流并在需要时切换。
public class SequenceInputStream extends InputStream { public SequenceInputStream(Enumeration<? extends InputStream> e); public SequenceInputStream(InputStream s1, InputStream s2); public int read(); public int read(byte[] b, int off, int len); public long skip(long n); public int available(); public void close(); }
上面的代码显示了 SequenceInputStream
提供的关键方法。 构造函数接受流的枚举或两个流。 该类自动处理所有流切换和 EOF 检测。
使用两个流创建 SequenceInputStream
创建 SequenceInputStream 最简单的方法是使用两个输入流。 构造函数接受两个 InputStream 对象,并从第一个对象读取直到 EOF,然后切换到第二个对象。 当 SequenceInputStream 关闭时,两个流都会被关闭。
import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.SequenceInputStream; public class Main { public static void main(String[] args) { String data1 = "First part of data. "; String data2 = "Second part of data."; try (ByteArrayInputStream stream1 = new ByteArrayInputStream(data1.getBytes()); ByteArrayInputStream stream2 = new ByteArrayInputStream(data2.getBytes()); SequenceInputStream seqStream = new SequenceInputStream(stream1, stream2)) { int byteData; while ((byteData = seqStream.read()) != -1) { System.out.print((char) byteData); } System.out.println("\nReading complete"); } catch (IOException e) { e.printStackTrace(); } } }
此示例将两个 ByteArrayInputStream 合并为一个 SequenceInputStream。 输出显示了来自两个流的连接数据。 try-with-resources 语句确保所有流都正确关闭。 SequenceInputStream 自动处理流之间的转换。
使用枚举创建 SequenceInputStream
对于两个以上的流,请使用 InputStreams 的枚举。 SequenceInputStream 将按枚举顺序读取每个流,直到所有流都耗尽。 这种方法对于组合多个数据源更加灵活。
import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.SequenceInputStream; import java.util.Collections; import java.util.Enumeration; import java.util.Vector; public class Main { public static void main(String[] args) { Vector<InputStream> streams = new Vector<>(); streams.add(new ByteArrayInputStream("First ".getBytes())); streams.add(new ByteArrayInputStream("Second ".getBytes())); streams.add(new ByteArrayInputStream("Third".getBytes())); Enumeration<InputStream> en = Collections.enumeration(streams); try (SequenceInputStream seqStream = new SequenceInputStream(en)) { int byteData; while ((byteData = seqStream.read()) != -1) { System.out.print((char) byteData); } System.out.println("\nAll streams read"); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示如何使用 Enumeration 来组合三个输入流。 Vector 存储流,Collections.enumeration 创建 Enumeration。 SequenceInputStream 按顺序读取每个流。 关闭 SequenceInputStream 时,所有流都将关闭。
将字节读入数组
为了获得更好的性能,一次将多个字节读入字节数组。 read 方法返回实际读取的字节数。 这适用于 SequenceInputStream 中的流边界。
import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.SequenceInputStream; import java.util.Vector; public class Main { public static void main(String[] args) { Vector<ByteArrayInputStream> streams = new Vector<>(); streams.add(new ByteArrayInputStream("Part1".getBytes())); streams.add(new ByteArrayInputStream("Part2".getBytes())); streams.add(new ByteArrayInputStream("Part3".getBytes())); try (SequenceInputStream seqStream = new SequenceInputStream(streams.elements())) { byte[] buffer = new byte[5]; int bytesRead; while ((bytesRead = seqStream.read(buffer)) != -1) { System.out.println("Read " + bytesRead + " bytes: " + new String(buffer, 0, bytesRead)); } System.out.println("All data read"); } catch (IOException e) { e.printStackTrace(); } } }
此示例显示了从 SequenceInputStream 的批量读取。 缓冲区大小为 5 个字节,与每个部分的长度匹配。 read 方法返回实际读取的字节,该字节可能小于缓冲区大小。 String 构造函数仅转换缓冲区的有效部分。
组合文件流
SequenceInputStream 特别适用于组合文件流。 此示例按顺序读取两个文件,就像它们是一个连续的流一样。 该方法适用于任何输入流组合。
import java.io.FileInputStream; import java.io.IOException; import java.io.SequenceInputStream; public class Main { public static void main(String[] args) { try (FileInputStream file1 = new FileInputStream("file1.txt"); FileInputStream file2 = new FileInputStream("file2.txt"); SequenceInputStream seqStream = new SequenceInputStream(file1, file2)) { int byteData; while ((byteData = seqStream.read()) != -1) { System.out.print((char) byteData); } System.out.println("\nBoth files read"); } catch (IOException e) { e.printStackTrace(); } } }
此示例将两个文件输入流组合成一个顺序流。 SequenceInputStream 在切换到 file2.txt 之前,先完全读取 file1.txt。 所有流都由 try-with-resources 块自动关闭。 这种模式对于将多个文件作为一个单元进行处理非常有用。
跨流跳过字节
skip 方法可在 SequenceInputStream 中的组合流之间使用。 它首先跳过当前流中的字节,然后在需要时继续进入后续流。 返回值指示实际跳过的字节数。
import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.SequenceInputStream; import java.util.Vector; public class Main { public static void main(String[] args) { Vector<ByteArrayInputStream> streams = new Vector<>(); streams.add(new ByteArrayInputStream("1234567890".getBytes())); streams.add(new ByteArrayInputStream("ABCDEFGHIJ".getBytes())); try (SequenceInputStream seqStream = new SequenceInputStream(streams.elements())) { // Skip first 5 bytes (from first stream) long skipped = seqStream.skip(5); System.out.println("Skipped " + skipped + " bytes"); // Read next 5 bytes (remaining from first stream) byte[] buffer = new byte[5]; seqStream.read(buffer); System.out.println("After skip: " + new String(buffer)); // Skip 3 bytes into second stream skipped = seqStream.skip(3); System.out.println("Skipped " + skipped + " more bytes"); // Read remaining from second stream seqStream.read(buffer); System.out.println("Final read: " + new String(buffer)); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示了跨多个流的跳过。 第一个 skip 在第一个流中运行。 第二个 skip 跨越到第二个流。 read 操作验证跳过位置。 skip 方法返回实际跳过的字节数,该字节数可能小于请求的字节数。
SequenceInputStream 中的可用字节
available 方法返回当前流中可用的字节数,而不会阻塞。 它不包括序列中后续流中的字节。 这种行为对于了解流状态很重要。
import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.SequenceInputStream; import java.util.Vector; public class Main { public static void main(String[] args) { Vector<ByteArrayInputStream> streams = new Vector<>(); streams.add(new ByteArrayInputStream("Short".getBytes())); streams.add(new ByteArrayInputStream("LongerData".getBytes())); try (SequenceInputStream seqStream = new SequenceInputStream(streams.elements())) { System.out.println("Initially available: " + seqStream.available() + " bytes"); // Read first stream completely byte[] buffer = new byte[10]; seqStream.read(buffer); System.out.println("After first read: " + seqStream.available() + " bytes available"); // Read part of second stream seqStream.read(buffer, 0, 3); System.out.println("After partial read: " + seqStream.available() + " bytes available"); } catch (IOException e) { e.printStackTrace(); } } }
此示例显示了 available 在 SequenceInputStream 中的行为方式。 最初,它仅报告来自第一个流的字节。 耗尽第一个流后,它将报告来自第二个流的字节。 available 计数随着从当前流中读取数据而减少。
来源
在本文中,我们介绍了 Java SequenceInputStream 类的基本方法和功能。 了解这些概念对于在 Java 应用程序中使用顺序 I/O 操作至关重要。
作者
列出所有Java教程。