【问题标题】:Java: InputStreams and OutputStreams being sharedJava:InputStreams 和 OutputStreams 被共享
【发布时间】:2012-11-23 10:27:06
【问题描述】:

我可以分享InputStreamOutputStream 吗?

例如,假设我首先拥有:

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

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

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

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

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

在整个手术后再次?

【问题讨论】:

  • 澄清...我在整个程序中严格使用“传入”,但在一种方法中,我需要传输大量文本,我希望为此使用 BufferedReader...但是,在它之后完成后,我想恢复正常流程并使用我的 DataInputStream 但现在它似乎消失了,或者至少无法读取任何内容..

标签: java inputstream outputstream datainputstream


【解决方案1】:

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

我知道流是具体的,从中读取会 消耗它的输入,不管它是从哪里完成的

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

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

【讨论】:

  • 哈哈,谢谢..虽然它们是同步的......这没问题......但是在我让那个拿着铲子的人(例如你!)进入洞之后,应该怎么做完成后我继续,以便我可以重新获得访问权限...这是我的问题!
  • 编辑后的帖子有更多示例。
  • 好示范!谢谢! :)
  • 很棒的解释!
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

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

    Multiple readers for InputStream in Java

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-14
      • 2017-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多