Java 理解 I/O 流

标签 java

Java 中的 I/O 流是我在编程中最容易被误解的概念。

假设,我们从套接字连接获取输入流:

DataInputStream in = new DataInputStream(clientSocket.getInputStream());

当我从远程服务器获取数据时,以下哪项描述正确?

  1. 数据存储在in 变量中。当额外的数据来自服务器时,它会附加到 in 中,增加其大小。然后我们可以通过这种方式从 in 变量中读取数据:

    byte[] messageByte = new byte[1000];
    boolean end = false;
    String dataString = "";
    while(!end)
    {
        bytesRead = in.read(messageByte);
        messageString += new String(messageByte, 0, bytesRead);
        if (messageString.length == 100)
        {
            end = true;
        }
    }
    
  2. in 只是指向数据源的链接,并不包含数据本身。当我们调用in.read(messageByte) 1000字节从套接字复制到bytesRead?

    或者,假设我们有流连接到 HDD 上的文件,而不是套接字。当我们调用 in.read(messageByte) 时,我们从 HDD 读取了 1000 个字节,是吗?

哪种方法是正确的?我倾向于认为它是#2,但如果是的话,套接字盒中的数据存储在哪里?当我们读取 1000 个字节时,远程服务器是否在等待,然后再次发送额外的数据?还是来自服务器的数据存储在操作系统的某个缓冲区中?

最佳答案

  1. Data stored in in variable.

没有。

When extra data comes from server, it appends to in, increase it size. And then we can read data from in variable that way:

byte[] messageByte = new byte[1000];
boolean end = false;
String dataString = "";
while(!end)
{
    bytesRead = in.read(messageByte);
    messageString += new String(messageByte, 0, bytesRead);
    if (messageString.length == 100)
    {
        end = true;
    }
}

没有。见下文。

  1. in is only link to source of data, and don't contains data themselves.

正确。

And when we call in.read(messageByte); 1000 bytes copy from socket to bytesRead?

没有。它阻塞直到:

  • 至少传输了一个字节,或者
  • 流结束,或者
  • 抛出异常,

以先发生者为准。请参阅 Javadoc。

(Instead socket, we can have stream connected to file on HDD, and when we call in.read(messageByte) we read 1000 bytes from HDD. Yes?)

没有。同上。

What approach right?

两者都不是。从输入流中读取的正确方法是循环,直到您拥有您期望的所有数据,或者 EOS 或发生异常。您不能依赖 read() 来填充缓冲区。如果需要,请使用 DataInputStream.readFully()

I tend to 2

这没有意义。你没有选择。 (1) 和 (2) 不是编程范例,它们是关于流实际如何工作的问题。如何编写代码的问题与此不同。

where data stored in socket?

其中一些在内核中的套接字接收缓冲区中。大部分还没到。没有一个是“在套接字中”。

Or remote server waiting when we read 1000 bytes, and then send extra data again?

没有。服务器通过其套接字发送缓冲区将数据发送到您的套接字接收缓冲区中。您的读取和服务器的写入彼此非常分离。

Or data from server stored in any buffer in operating system?

是的,套接字接收缓冲区。

关于Java 理解 I/O 流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33029597/

相关文章:

java - 如何阻止应用程序日志登录到 Tomcat 中的 catalina.out

java - 使用 Windows 安装程序分发 Java Web 应用程序

java - 如何从给定列表中获取包含更多小写字符的字符串?

java - 为什么这个 switch case 在 Netbeans 中不起作用?

java - 如何从 POM.xml 中读取 application.properties

java - 添加要在 Jar 中构建的文本文件和图像 - Netbeans

java - Spring 安全: Set Remember me Service while using AbstractPreAuthenticatedProcessingFilter

java - 查找 http URL 路径的困境

java - 如何随机选择一个类的实例并执行它的方法?

java - 创建依赖于 RESTlet 的 Maven Artifact - 如何处理版本