简体   繁体   English

HTTPURLConnection.getInputStream()需要很长时间?

[英]HTTPURLConnection.getInputStream() Takes a very long time?

I'm uploading an image file using a HttpURLConnection which takes about 3 seconds for a 5MB file with all the headers, but the moment I open an InputStream with .getInputStream(), the method takes about 8+ seconds to return a stream with. 我正在使用HttpURLConnection上传一个图像文件,对于带有所有标题的5MB文件大约需要3秒钟,但是当我用.getInputStream()打开一个InputStream时,该方法需要大约8秒以上才能返回一个流。 Which is an issue because it seems the upload progress bar gives a bad UX if I have multiple images to upload, they have a considerable pause between each upload, so the progress bar just stops for a couple of seconds between uploads. 这是一个问题,因为如果我要上传多个图像,上传进度条似乎提供了一个糟糕的用户体验,它们在每次上传之间有相当大的暂停,因此进度条在上传之间停止几秒钟。 I've done some googling but no one else seems to have an issue with it? 我做了一些谷歌搜索,但似乎没有其他人有问题吗?

Normally I would assume the server is slow, but seeing as uploading only takes a couple of seconds, downloading the word 'success' or 'fail' shouldn't really be that much of an issue! 通常我认为服务器很慢,但看上传只需要几秒钟,下载“成功”或“失败”这个词应该不是真正的问题!

Heres some code! 这是一些代码! Am I setting anything up wrong initially? 我最初设置错误了吗? Note: This is also within an AsyncTask 注意:这也在AsyncTask中

    ByteArrayInputStream fileInputStream = null;

    try {
        fileInputStream = new ByteArrayInputStream(dObject.Data);

    } catch (Exception e) {
        e.printStackTrace();
    }


    String lineEnd = "\r\n";
    String twoHyphens = "--";
    String boundary = "*****";
    String Tag="3rd";
    try
    {
        //------------------ CLIENT RE QUEST        
        Log.e(Tag,"Inside second Method");      

        // Open a HTTP connection to the URL    
        URL url = new URL(_urlString);
        //connectURL is a URL object
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

        // Allow Inputs
        conn.setDoInput(true);

        // Allow Outputs
        conn.setDoOutput(true);

        // Don't use a cached copy.
        conn.setUseCaches(false);

        // Use a post method.
        conn.setRequestMethod("POST");

        conn.setRequestProperty("Connection", "Keep-Alive");

        conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);

        DataOutputStream dos = new DataOutputStream( conn.getOutputStream() );

        dos.writeBytes(twoHyphens + boundary + lineEnd);
        //dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + _fileLocation +"\"" + lineEnd);
        dos.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\"" + _fileLocation +"\"" + lineEnd);

        dos.writeBytes(lineEnd);

        Log.e(Tag,"Headers are written");

        // create a buffer of maximum size
        int bytesAvailable = fileInputStream.available();
        int maxBufferSize = 1024;
        int bufferSize = Math.min(bytesAvailable, maxBufferSize);
        byte[] buffer = new byte[bufferSize];



        // read file and write it into form...  
        int bytesRead = fileInputStream.read(buffer, 0, bufferSize);


        while (bytesRead > 0) {
            dos.write(buffer, 0, bufferSize);

            //int value = (int)(((float)((float)totalRead / (float) fileSize)) * 100);

            totalRead += bytesRead;
            //Publish the progress out to be displayed
            publishProgress(totalRead);



            bytesAvailable = fileInputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);
        }

        // send multipart form data necesssary after file data...
        dos.writeBytes(lineEnd);
        dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);


        // close streams
        Log.e(Tag,"File is written");
        fileInputStream.close();
        dos.flush();

        Log.e("TIME", "PRE GETINPUTSTREAM");
        InputStream is = conn.getInputStream(); 
        Log.e("TIME", "POST GETINPUTSTREAM");
        //  retrieve the response from server
        int ch;


        //Build the respose and log
        StringBuilder b =new StringBuilder();
        while( ( ch = is.read() ) != -1 ){
            b.append( (char)ch );
        }
        String s=b.toString();      
        Log.i("Response",s);
        dos.close();

        return;
    }
    catch (MalformedURLException ex)
    {
        ErrorHandler.get().e("3");
    }

    catch (IOException ioe)
    {
        ErrorHandler.get().e("2");
    }

Normally I would assume the server is slow, but seeing as uploading only takes a couple of seconds, downloading the word 'success' or 'fail' shouldn't really be that much of an issue! 通常我认为服务器很慢,但看上传只需要几秒钟,下载“成功”或“失败”这个词应该不是真正的问题!

I suspect that it really is that the server is slow or overloaded. 我怀疑它确实是服务器缓慢或过载。

  • The server could be queueing the HTTP requests and only processing a small number at a time in parallel. 服务器可以对HTTP请求进行排队,并且只能并行处理少量数据。

  • Or it could have a bottleneck in some database activity that is performed before the response containing the file is written to the response. 或者,在将包含该文件的响应写入响应之前执行的某些数据库活动可能存在瓶颈。

  • Or it could be generating the file on the fly into an in-memory buffer (slow) and then streaming (fast) from the buffer to the HTTP response. 或者它可以将文件动态生成到内存缓冲区(慢),然后从缓冲区流式传输(快速)到HTTP响应。

  • Or other explanations like this ... 或者像这样的其他解释......

(It is also theoretically possible that there is something funny going on that slows up the delivery of the request to the server. I would think this was unlikely though.) (理论上也可能有一些有趣的事情会减慢向服务器发送请求的速度。我认为这不太可能。)


Have you tried downloading the same file using a web browser? 您是否尝试使用Web浏览器下载相同的文件? Do you get the same behaviour there? 你在那里得到同样的行为吗?

In my case I found that getInputStream looks slow because this method initialize the ssl handshake (on a https URL call). 在我的情况下,我发现getInputStream看起来很慢,因为这个方法初始化ssl握手(在https URL调用上)。 After the first call, others calls are OK 第一次通话后,其他通话都可以

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM