java - 您能解释一下流的概念吗?

标签 java .net stream language-agnostic iostream

我理解流是字节序列的表示。每个流都提供了向其给定的后备存储读取和写入字节的方法。但流的意义何在?为什么我们与之交互的不是后备存储本身?

无论出于何种原因,这个概念都不适合我。我读过很多文章,但我想我需要一个类比或其他东西。

最佳答案

选择“流”这个词是因为它(在现实生活中)代表的含义与我们使用它时想要传达的含义非常相似。

让我们暂时忘记后备存储,并开始考虑与水流的类比。您会收到连续的数据流,就像河中的水不断流动一样。您不一定知道数据来自哪里,而且大多数情况下您也不需要知道;无论是来自文件、套接字还是任何其他来源,这并不(不应该)真正重要。这与接收一股水流非常相似,你不需要知道它从哪里来;你只需知道它是从哪里来的。无论是来自湖泊、喷泉还是任何其他来源,这并不(不应该)真正重要。

也就是说,一旦您开始认为您只关心获取所需的数据,无论数据来自何处,其他人谈论的抽象就会变得更加清晰。您开始认为您可以包装流,并且您的方法仍然可以完美工作。例如,您可以这样做:

int ReadInt(StreamReader reader) { return Int32.Parse(reader.ReadLine()); }

// in another method:
Stream fileStream = new FileStream("My Data.dat");
Stream zipStream = new ZipDecompressorStream(fileStream);
Stream decryptedStream = new DecryptionStream(zipStream);
StreamReader reader = new StreamReader(decryptedStream);

int x = ReadInt(reader);

如您所见,更改输入源变得非常容易,而无需更改处理逻辑。例如,要从网络套接字而不是文件读取数据:

Stream stream = new NetworkStream(mySocket);
StreamReader reader = new StreamReader(stream);
int x = ReadInt(reader);

尽可能简单。美丽还在继续,因为您可以使用任何类型的输入源,只要您可以为其构建一个流“包装器”。你甚至可以这样做:

public class RandomNumbersStreamReader : StreamReader {
    private Random random = new Random();

    public String ReadLine() { return random.Next().ToString(); }
}

// and to call it:
int x = ReadInt(new RandomNumbersStreamReader());

看到了吗?只要您的方法不关心输入源是什么,您就可以通过各种方式自定义源。抽象允许您以一种非常优雅的方式将输入与处理逻辑解耦。

请注意,我们自己创建的流没有后备存储,但它仍然可以完美地满足我们的目的。

因此,总而言之,流只是一个输入源,隐藏(抽象)另一个源。只要不破坏抽象,您的代码就会非常灵活。

关于java - 您能解释一下流的概念吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1216380/

相关文章:

java - 如何在 Eclipse 中找到抽象方法的实现位置?

java - 如何将 Spring Boot 项目连接到 SonarQube

c# - 使用我的 C# 应用程序从谷歌浏览器中获取文本

c - 为什么我的 nanosleep 不起作用...?

c++ - 状态机回放的流数据

java - Docker和Java套接字: Share data between containers

java - 使用 JUnit 测试具有 @PreAuthorize 的服务方法

java - 在 JAX-RS 服务中获取 XML

.net - 具有完整 .NET Framework 和 Angular 2 的 ASP.NET Core

.net - 有哪些不同的 CLR 句柄类型?