【问题标题】:Why does HTTPURLConnection.getInputStream() takes time为什么 HTTPURLConnection.getInputStream() 需要时间
【发布时间】:2014-05-29 23:38:56
【问题描述】:

我的任务是在 Android(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 英里秒)来执行。这是否意味着它此时正在与网络通信?如果是,那为什么会这样?

专家,如果我在任何地方有错误,请提供您的 cmet 并纠正我。

【问题讨论】:

    标签: java android network-programming inputstream


    【解决方案1】:

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

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

    【讨论】:

    • 感谢您的快速回复。如果我理解正确,那么它的意思是:当我们调用 getOutputStream 时,它没有与网络连接,而是创建了 1 个介质来写入数据。当我们在此输出流中写入字节时,它会与网络通信以上传这些字节。但是当我们调用 getInputStream 时,Java API 会设置一些内容长度标头并将此请求发送到服务器,然后等待服务器回复。在这里它与网络交互。
    • 没有。读我写的。 '此时尚未向网络写入任何内容'。
    【解决方案2】:

    您必须通过指定流模式来限制缓冲,方法是通过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

    【讨论】:

      猜你喜欢
      • 2011-11-20
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-14
      • 2011-04-22
      • 2015-12-16
      相关资源
      最近更新 更多