为什么HTTPURLConnection.getInputStream()需要时间

3

我需要在安卓(Java平台)上使用HTTP协议下载和上传文件。

我正在使用以下代码上传文件:

HttpURLConnection httpURLConnection = (HttpURLConnection) serverUrl.openConnection();
....
httpURLConnection.connect();
OutputStream os = httpURLConnection.getOutputStream();

使用以下代码下载文件:

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
...
urlConnection.connect();
DataInputStream stream = new DataInputStream(urlConnection.getInputStream());

根据我的观察,对于两种情况,connect() 都需要时间,因为在这个时候它正在与网络通信。而对于文件上传,getOutputStream() 很快就会执行,这是不是意味着它没有与网络通信?
然而,在文件下载中,getInputStream() 需要一些时间(大约200到2500毫秒)才能执行。这是不是意味着它在这个时候正在与网络通信?如果是的话,为什么会这样呢?
专家们,请提供您的评论并指出我哪里有错。
2个回答

1

您必须通过指定流模式来限制缓冲,可以通过使用setFixedLengthStreamingMode方法给出上传信息的最终长度或者通过setChunkedStreamingMode方法将模式设置为流模式(如果最终长度未知):

    // For best performance, you should call either setFixedLengthStreamingMode(int) when the body length is known in advance,
    // or setChunkedStreamingMode(int) when it is not. Otherwise HttpURLConnection will be forced to buffer the complete request body in memory
    // before it is transmitted, wasting (and possibly exhausting) heap and increasing latency.
    //
    // see: https://developer.android.com/reference/java/net/HttpURLConnection.html

    _connection.setChunkedStreamingMode(1024);

如果您不这样做,真正的传输将发生在调用getInputStream()时。
请参见https://developer.android.com/reference/java/net/HttpURLConnection.html

1

HTTP是一种请求/响应协议。您需要一个TCP连接。connect()方法创建它。然后您需要发送请求。为此,您调用getOutputStream(),并将其写入。

在此时,还没有向网络中写入任何内容(在正常传输模式下),因为必须设置内容长度标头,并且Java不知道您何时完成写入。因此,当您调用getInputStream()(或getResponseCode())时,Java设置内容长度标头,写入请求,等待服务器开始生成响应,读取所有响应标头,然后提供定位在响应正文开头的输入流。所有这些步骤都需要时间。


感谢您的快速回复。如果我理解正确,那么它的意思是:当我们调用getOutputStream时,它并没有连接到网络,而是创建了一个中介来写入数据。当我们在此输出流中写入字节时,它会与网络通信以上传这些字节。但是当我们调用getInputStream时,Java API会设置一些content-length头并将此请求发送到服务器,然后等待服务器回复。在这里它正在与网络交互。 - Shravan
没有。看清楚我写的话。“此时还没有向网络中写入任何内容”。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接