2

我可以分享一个InputStreamorOutputStream吗?

例如,假设我首先有:

DataInputStream incoming = new DataInputStream(socket.getInputStream()));

...incoming作为一个对象变量。后来我暂时做:

BufferedReader dataReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

我知道流是具体的,并且从它读取它会消耗它的输入,无论它是从哪里完成的......但是在完成上述操作之后,我仍然可以同时访问两者还是incoming只是连接到一个对象并因此丢失它一旦我声明输入?我知道如果我关闭然后我也会关闭套接字并且我会避免这样做但是我想知道在将它“转移”到之后是否需要以某种方式“回收”它?我必须这样做吗:dataReaderInputStreamincomingdataReaderdataReaderInputStreamincomingdataReader

incoming = new DataInputStream(socket.getInputStream());

在整个手术之后再次?

4

3 回答 3

4

您正在使用茶匙和铲子从孔中清除污垢。

我知道流是具体的,从它读取将消耗它的输入,无论它是从哪里完成的

正确的。茶匙和铲子都可以从孔中清除污垢。如果您正在异步(即同时)清除污垢,您可能会为谁拥有什么污垢而争吵 - 所以使用并发构造来提供互斥访问。如果访问不是并发的,换句话说......

1)从孔中移出一或多茶匙污垢
2)从孔中移出一或多铲污垢
3)从孔中移出一或多茶匙污垢
...

没问题。茶匙和铲子都可以去除污垢。但是一旦污垢被去除,它就会被去除,它们不会得到同样的污垢。希望这可以帮助。让我们开始铲,我会用茶匙。:)

正如快速反应所发现的那样,在共享流时要非常小心,尤其是缓冲的阅读器,因为它们可以从流中吞噬比他们需要的更多的字节,所以当你回到你的其他输入流(或阅读器)时,它可能看起来像一大堆字节已被跳过。

证明您可以从相同的输入流中读取:

import java.io.*;

public class w {

    public static void main(String[] args) throws Exception {

        InputStream input = new FileInputStream("myfile.txt");
        DataInputStream b = new DataInputStream(input);

        int data, count = 0;

        // read first 20 characters with DataInputStream
        while ((data = b.read()) != -1 && ++count < 20) {
            System.out.print((char) data);
        }
        // if prematurely interrupted because of count
        // then spit out last char grabbed
        if (data != -1)
            System.out.print((char) data);

        // read remainder of file with underlying InputStream
        while ((data = input.read()) != -1) {
            System.out.print((char) data);
        }
        b.close();
    }
}

输入文件:

hello OP
this is
a file
with some basic text
to see how this
works when moving dirt
from a hole with a teaspoon
and a shovel

输出:

hello OP
this is 
a file
with some basic text
to see how this
works when moving dirt
from a hole with a teaspoon
and a shovel

证明 BufferedReader 不能保证工作,因为它会从流中吞噬大量字符:

import java.io.*;

public class w {

    public static void main(String[] args) throws Exception {

        InputStream input = new FileInputStream("myfile.txt");
        BufferedReader b = new BufferedReader(new InputStreamReader(input));

        // read three lines with BufferedReader
        String line;
        for (int i = 0; (line = b.readLine()) != null && i < 3; ++i) {
            System.out.println(line);
        }

        // read remainder of file with underlying InputStream
        int data;
        while ((data = input.read()) != -1) {
            System.out.print((char) data);
        }
        b.close();
    }
}

输入文件(同上):

hello OP
this is
a file
with some basic text
to see how this
works when moving dirt
from a hole with a teaspoon
and a shovel

输出:

hello OP
this is
a file
于 2012-12-05T15:01:02.387 回答
1

这将是灾难性的。两个流都将具有损坏的数据。Java 怎么可能知道将哪些数据发送到哪个 Stream?

如果您需要用相同的数据做两件不同的事情,最好将它存储在某个地方(可能将其复制到两个Queue<String>),然后以这种方式读取它。

于 2012-12-05T14:57:17.970 回答
1

好的,我自己解决了这个问题。有趣的链接:

http://www.coderanch.com/t/276168//java/InputStream-multiple-Readers

Java 中 InputStream 的多个阅读器

基本上......InputStream可以连接到多个对象,从中读取并使用它。但是,a会提前读取,因此当涉及其中一个时,当您从例如 a 切换到 aBufferedReader时实现某种信号可能是一个好主意(也就是说,您想使用突然而不是)。因此,一旦我知道所有要处理的数据都已发送,我就停止向其发送数据。在此之后,我等待另一部分处理它应该使用. 然后它会发送一个信号以表明它已准备好接受新的输入。发送部分应该是阻塞的,直到它接收到信号输入,然后它才能再次开始发送数据。如果我不使用BufferedReaderDataInputStreamDataInputStreamInputStreamBufferedReaderInputStreamBufferedReaderBufferedReaderBufferedReader在此之后,它将没有机会缓冲所有输入并从中“窃取”它,DataInputStream并且一切都运行良好:) 但是请注意,从 中进行一次读取操作BufferedReader,您将回到相同的情况。 .. 很高兴知道!

于 2012-12-05T17:02:51.993 回答