【问题标题】:How is an Input Stream different from an Output Stream?输入流与输出流有何不同?
【发布时间】:2012-12-04 07:33:53
【问题描述】:

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

评论 - 请不要关闭此问题。这是一种基本的东西,可以 在采访中让人们感到困惑。

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

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

【问题讨论】:

  • 是的,就是这么简单。这是一个观点问题——你在“流”的哪一端。例如,查看 java 中的 ProcessBuilder 类。它允许您从您的 java 进程启动一个进程,然后该进程的输出流是您的输入流,反之亦然。
  • 我也在考虑这些答案,我也想知道是否还有其他原因。我的猜测是,虽然这是原生 IO 的区别......
  • @Thihara - 是的,对我来说这看起来微不足道。但是,我觉得我们也需要看看这个 - 如果差异不是那么“大”,那么我们是否可以拥有一个 InAndOutStream 而不必为两个类(InputStream 和 OutputStream)编写代码?
  • 基本的“流”概念是单向的(顾名思义)——所以有 2 个实现
  • “每个人似乎都在说同样的话——你从 IS 读取并写入 OS。所以,它们基本上是相同的”。不,他们不是。数据流的概念是一样的,但是写入和读取是不同的操作。为它们提供不同的类可以简化它们的实现和 API - 没有程序员会尝试从输出流中读取错误,因为编译器会阻止他调用读取方法。如果连续调用读取和写入,则实现不必跟踪幕后发生的事情。

标签: java inputstream outputstream


【解决方案1】:

您读取 InputStream,然后写入 OutputStream。这是它们之间的主要区别。

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

【讨论】:

  • @davidblaine:是的,就是这么简单。
  • 如果差异不是那么“大”,那么我们是否可以拥有一个 InAndOutStream 而不必为两个类(InputStream 和 OutputStream)编写代码?
  • 在概念上是的。但我不知道原生低级 IO,所以可能会有区别..
【解决方案2】:

它们在概念上是不同的

  • 来自InputStream你阅读
  • 给OutputStream你写

【讨论】:

  • @davidblaine,是的,这很简单,因为 InputStream 和 OutputStream 是抽象类。一旦子类以不同的方式实现这些方法,它就会变得更加复杂。
  • 如果差异不是那么“大”,那么我们是否可以拥有一个 InAndOutStream 而不必为两个类(InputStream 和 OutputStream)编写代码?
  • @davidblaine,但是您在运行时的InAndOutStream 无论如何都必须是输入或输出,而不是同时输入或输出,所以会令人困惑。
  • 我不确定这意味着什么。我想这就是您要说的-我们需要知道流在哪种“模式”下运行,即读取或写入?出于这个原因,我们有 IS 和 OS 而不是 InAndOutStream。或者,我们可以在 InAndOutStream 类中有一个变量,它告诉我们流的模式——即输入或输出。但这会很麻烦,我猜。
  • 最好不要在你的程序中混合它们,因为这些类型可以帮助你跟踪你应该对每个流做什么。
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

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

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

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

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

    【讨论】:

    • 您能否详细说明the reader and writer of the stream occupy radically different positions in the execution environment 或指向有更多信息的文章?
    • 我想我已经详细说明了。我不确定我还能说什么。
    • @Dolda2000 - 我是新手,不熟悉协同程序等。我在 wiki 上看到它,但无法看到它与我的问题有什么关系。你能用更简单的语言解释一下吗,也许可以打个比方?
    【解决方案5】:

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

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

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

    【讨论】:

      【解决方案6】:

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

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

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

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

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

      【讨论】:

        【解决方案7】:

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

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

        //Standard input: 
        Scanner scan = new Scanner(System.in);
        String s = scan.next();
        
        //Standard output
        System.out.println("Hello World!");
        

        【讨论】:

          猜你喜欢
          • 2018-05-25
          • 1970-01-01
          • 2019-01-25
          • 2014-01-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多