如何使用管道 IO 流

How to use Piped IO Streams

来自 PipedInputStream and PipedOutputStream 的文档, 前者构成通信管道的接收端,后者为发送端。这形成了这样的结构:
A -> PipedInputStream -> PipedOutputStream -> B
我的问题是如何指定 A 和 B 是什么。我希望 A 成为标准输入流 System.in,B 成为 FileOutputStream.
如果我错了请纠正我,但我认为 Piped Stream 对象提供了一种将 InputStream 连接到 OutputStream 的方法。但是我没有看到任何方法可以将 PipedInputStream 连接到 PipedOutputStream 以外的任何东西,反之亦然。

PipedInputStreamPipedOutputStream 用于在两个线程之间创建管道。

通常你会做这样的事情:

  • 创建一个 PipedOutputStream 和一个 PipedInputStream 并连接它们
  • 启动一个写入 PipedOutputStream
  • 的线程
  • 启动一个从 PipedInputStream
  • 读取的线程

首先沟通的方向是
A -> PipedOutputStream -> PipedInputStream -> B.

无法将 AB 设置为某些特定流。
A简单的表示一个线程调用PipedOutputStreamwrite()方法提交一些数据,然后从另一个线程传给PipedInputStream B可以用read()的方法读取。

您链接到 PipedOutputStream 的 javadoc,但您似乎没有阅读它。

A piped output stream can be connected to a piped input stream to create a communications pipe. The piped output stream is the sending end of the pipe. Typically, data is written to a PipedOutputStream object by one thread and data is read from the connected PipedInputStream by some other thread.

因此,数据流向与问题显示的方向相反:

Thread A  →  PipedOutputStream  →  PipedInputStream  →  Thread B

如您所见,我还通过显示AB线程来澄清它,即代码,而不是其他流.


Correct me if I am wrong, but I think the Piped Stream objects offer a way to connect an InputStream to an OutputStream.

从上面的描述可以看出,你错了。 Piped Stream 对象为线程提供了一种使用 Stream I/O 调用将数据发送到另一个线程的方法。

它们被称为“管道”,因为它的工作方式类似于一个程序可以写入标准输出,另一个程序可以从标准输入读取,然后您可以使用 | 管道连接两者,例如foo.exe | bar.exe 会将 foo 程序的输出作为 bar 程序的输入。

那只是在 进程 之间,而管道流在 线程 .

之间

I would like A to be the standard input stream System.in and B to be a FileOutputStream.

如果要从 System.in 复制到文件,可以执行以下任一操作:

// Using newer NIO.2 API (Java 7+)
Files.copy(System.in, Paths.get(filename), StandardCopyOption.REPLACE_EXISTING);
// Using old File I/O API with transferTo (Java 9+)
try (FileOutputStream out = new FileOutputStream(new File(filename))) {
    System.in.transferTo(out);
}
// Using old File I/O API with try-with-resources (Java 7+)
try (FileOutputStream out = new FileOutputStream(new File(filename))) {
    byte[] buf = new byte[8192];
    for (int len; (len = System.in.read(buf)) > 0; )
        out.write(buf, 0, len);
}
// Using old File I/O API (any Java version)
FileOutputStream out = new FileOutputStream(new File(filename));
try {
    byte[] buf = new byte[8192];
    for (int len; (len = System.in.read(buf)) > 0; )
        out.write(buf, 0, len);
} finally {
    out.close();
}