better method to upload/download multiple files to the server

徘徊边缘 提交于 2019-12-11 05:44:18

问题


I tried to use :

@Override
    protected String doInBackground(Void... params) {
        // TODO Auto-generated method stub
        String path = "http://192.168.1.112/johnson/learn/android/uploads/";
        String sUrl1 = "productSock";
        String sUrl2 = "productHistory";
        downloadFile(path, sUrl2);
        downloadFile(path, sUrl1);
        return null;
    }

    private boolean downloadFile(String path, String sUrl) {
        // TODO Auto-generated method stub
        try {
            String toUrl = path + sUrl;
            URL url = new URL(toUrl);
            URLConnection connection = url.openConnection();
            connection.connect();
            // this will be useful so that you can show a typical 0-100%
            // progress bar
            int fileLength = connection.getContentLength();

            // download the file
            InputStream input = new BufferedInputStream(url.openStream());
            OutputStream output = new FileOutputStream(Environment
                    .getExternalStorageDirectory().getAbsolutePath()
                    + "/Android/data/com.android.avs.amp.inventory/files/"
                    + sUrl);

            byte data[] = new byte[1024];
            long total = 0;
            int count = 0;
            while ((count = input.read(data)) != -1) {
                total += count;
                // publishing the progress....
                publishProgress((int) (total * 100 / fileLength));
                output.write(data);
            }
            output.flush();
            output.close();
            input.close();
        } catch (Exception e) {
        }
        return true;
    }

when upload the second file it stuck at 31% sometimes also stuck at the 1st file on 0%

how to change the code? or any other methods?

And my upload

@Override
    protected Boolean doInBackground(Void... params) {
        // TODO Auto-generated method stub
        uploadFile("productStock");
        uploadFile("productHistory");
        return false;
    }

    private void uploadFile(String path) {
        // TODO Auto-generated method stub
        HttpURLConnection conn = null;
        DataOutputStream dos = null;
        DataInputStream inStream = null;
        String existingFileName = Environment.getExternalStorageDirectory().getAbsolutePath()+ "/Android/data/com.android.avs.amp.inventory/files/"+path;
        String lineEnd = "\r\n";
        String twoHyphens = "--";
        String boundary = "*****";
        int bytesRead, bytesAvailable, bufferSize;
        byte[] buffer;
        int maxBufferSize = 1 * 1024 * 1024;
        String responseFromServer = "";
        String urlString = "http://192.168.1.112/johnson/learn/android/";
        try {
            // ------------------ CLIENT REQUEST
            FileInputStream fileInputStream = new FileInputStream(new File(
                    existingFileName));
            // open a URL connection to the Servlet
            URL url = new URL(urlString);
            // Open a HTTP connection to the URL
            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);
            dos = new DataOutputStream(conn.getOutputStream());
            dos.writeBytes(twoHyphens + boundary + lineEnd);
            dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\""
                    + existingFileName + "\"" + lineEnd);
            dos.writeBytes(lineEnd);
            // create a buffer of maximum size
            bytesAvailable = fileInputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            buffer = new byte[bufferSize];
            // read file and write it into form...
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);
            while (bytesRead > 0) {
                dos.write(buffer, 0, bufferSize);
                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
            fileInputStream.close();
            dos.flush();
            dos.close();
        } catch (MalformedURLException ex) {
            // Log.e("Debug", "error: " + ex.getMessage(), ex);
            mErrorMsg = "error: " + ex.getMessage();
        } catch (IOException ioe) {
            // Log.e("Debug", "error: " + ioe.getMessage(), ioe);
            mErrorMsg = "error: " + ioe.getMessage();
        } 
        // ------------------ read the SERVER RESPONSE
        try {
            inStream = new DataInputStream(conn.getInputStream());
            String str;

            while ((str = inStream.readLine()) != null) {
                // Log.e("Debug", "Server Response " + str);
                mErrorMsg = "Upload Successful";
            }
            inStream.close();

        } catch (IOException ioex) {
            // Log.e("Debug", "error: " + ioex.getMessage(), ioex);
            mErrorMsg = "error: " + ioex.getMessage();
        }
    }

When the file to upload is not exist, it will stuck at progress dialog or is there any better method to upload multiple files?

Thanks in advance


回答1:


I'm not sure what causes your code to hang at a certain percentage, but I can tell you why it will produce corrupted data.

In the Upload/Download code you use this method to write your read bytes:

stream.write(buffer, 0, bufferSize);

Now, the problem with this is, that you're giving the write(byte[], int, int)-method the wrong parameter for the length.

When reading from a stream, the read()-method returns:

Returns: the total number of bytes read into the buffer, or -1 if there is no more data because the end of the stream has been reached.

That means, even thought your byte[] array is buffer_size bytes long (for example 1024), this does not mean that 1024 bytes where read (it might be less, e.g. the buffer might not be full). The actual amount of bytes read is returned by the read()-method.

Therefor, you're giving the write()-method the wrong amount of bytes to write, which causes it to write null-bytes that corrupt your file.

The correct implementation looks like this:

byte data[] = new byte[1024];
int read_count = 0;
while ((read_count = input.read(data, 0, data.length)) != -1) {
    output.write(data, 0, read_count);
}

If you're not uploading binary data, you're normally better off using an already buffered writer-implementation (like BufferedWriter / BufferedReader).


I covered this topic in a little more detail in this Blogpost: Working unbuffered streams



来源:https://stackoverflow.com/questions/11898962/better-method-to-upload-download-multiple-files-to-the-server

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!