6

我看到两者都是数据的“流”。在那种情况下,为什么认为它们不同?真的有什么区别?

评论 - 请不要关闭这个问题。这是在面试中可以使人们感到困惑的基本内容。

更新 1 - 每个人似乎都在说同样的话 - 你从 IS 读取并写入操作系统。所以,它们基本上是一样的。就像有水流过的管道。当您使用该管道中的水时,您将其称为 InputStream,当您将水泵入其中时,它称为输出流。真的那么微不足道吗?

UPDATE2 - 如果差异不是那么“大”,那么我们是否可以拥有一个 InAndOutStream 而不必为两个类(InputStream 和 OutputStream)编写代码?

4

7 回答 7

16

它们在概念上是不同的

  • InputStream你读
  • OutputStream你写
于 2012-12-17T07:52:46.120 回答
5

流是您按顺序访问的数据。你可以把它想象成从隧道入口看到的火车,这样你一次只能看到一辆车。或者一串小部件穿过传送带,要求你在每个小部件上拧紧一个螺丝,然后它才能传递给流水线上的下一个必须用锤子敲打它的人,依此类推。或者当您从桥上观看时,木棍顺流而下。

无论它们在内部如何工作,所有流都向使用它们的程序呈现相同的简单模型:流是数据序列。程序使用输入流从源中读取数据,一次读取一项: IO 流

程序使用输出流将数据写入目标,一次写入一项: IO 流

于 2012-12-17T08:08:56.630 回答
4

如果差异不是那么“大”,那么我们是否可以拥有一个 InAndOutStream 而不必为两个类(InputStream 和 OutputStream)编写代码?

除了 ByteArray 类之外,这是不可能的。原因是大多数 Streams 都由系统提供的设备(例如文件或套接字)支持。在文件的情况下,您写入的文件是您从中读取的文件,但在套接字的情况下,您写入的流与您读取的流无关。

恕我直言,即使尝试将它们结合起来也是一个坏主意,因为人们在文本和二进制流之间感到困惑。如果他们可以读写同一个流,我怀疑你会更加困惑。

一般来说,开发人员应该清楚地知道他们是从设备读取还是写入。如果他们不清楚,你肯定会遇到问题。

仅供参考:我已经编写了一个库,它完全按照您在内存流中的建议,如“管道”;)但是,我会说它只适用于专家开发人员,即使这样我也会尽可能地保持接口不同以防止混淆。

于 2012-12-17T08:39:35.953 回答
2

您从读取InputStream然后写入OutputStream这是他们之间的关键区别。

在某些情况下,您需要能够读写。一个这样的例子是流套接字。Java 库处理此问题的方式是使用一个InputStream 一个OutputStream.

于 2012-12-17T07:52:06.267 回答
2

流的概念并不像您在问题中暗示的那样对称。由于这是 Java,流的读取器和写入器在执行环境中占据完全不同的位置:一个实现流对象,另一个调用它的方法。

因此,由于语言强制模型上的不对称性,Java 中任何 I/O 工具的实现者都需要提前确定是占据流的读取端还是写入端。该设施的用户没有选择权。例如,然后;为了实现一个从用户那里接收数据的 I/O 工具,需要实现一个OutputStream(用户会调用它来写入)。

为了实现对称设施,语言需要能够协同执行。在这种情况下,流可以真正具有可读和可写的一面,而试图写入的调用者将屈服于读者,反之亦然。然而,Java 不支持这样的工具。(至少在多线程之外,这对于大多数情况来说显然太重了。)

我希望这让它更清楚一点。

于 2012-12-17T08:06:29.670 回答
0

我最好的选择是保持它们很小,当用户只打算读取流时,为什么要加载用于写入流的函数?不过,这纯粹是基于我的猜测...

编辑:我对word文件很傻,流不仅可以用于文件。

于 2012-12-17T07:53:42.330 回答
0

为了避免流之间的混淆,例如html注册表单,进入表单的数据称为input-data,一旦注册成功或失败输出称为out-data。与应用程序通过输入流接收数据的方式相同,应用程序通过输出流发送数据。

以下代码帮助我们避免流之间的混淆:

//Standard input: 
Scanner scan = new Scanner(System.in);
String s = scan.next();

//Standard output
System.out.println("Hello World!");
于 2017-06-19T04:19:21.743 回答