6

我正在使用此代码在服务器上上传文件,但我想要这样的功能:如果它由于丢失网络或过程中的任何其他中断而停止,那么它不应该从第二次开始上传。服务器的响应也是可定制的。安卓有可能吗?我应该使用什么方法来做到这一点?请指导我。如果可能的话,请向我推荐任何示例代码。

谢谢!

public String uploadFile(InputStream is) {
    HttpURLConnection conn;
    String jsonResponse = "";
    int streamSize = 0;
    DataOutputStream dos = null;
    DataInputStream inStream = null;
    String lineEnd = "\r\n";
    String twoHyphens = "--";
    String boundary = "*****";
    int bytesAvailable, bufferSize;
    byte[] buffer;

    String urlString = "*******<My URL>*******";
    try {
        // ------------------ CLIENT REQUEST
        // FileInputStream fileInputStream = new FileInputStream(new
        // File(selectedPath) );

        // 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);

        conn.setChunkedStreamingMode(0);
        // 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=\"wheeze_file\";filename="
                + fileName + lineEnd);
        dos.writeBytes(lineEnd);

        // create a buffer of maximum size
        bytesAvailable = is.available();
        streamSize = bytesAvailable;
        bufferSize = 2048;
        buffer = new byte[bufferSize];
        // read file and write it into form...
        int i = 0;
        int length = 0;
        while ((length = is.read(buffer, 0, bufferSize)) > 0) {
            if (isCancelled()) {
                Toast.makeText(getApplicationContext(), "Cancelled",
                        Toast.LENGTH_SHORT).show();
                return null;
            }
            dos.write(buffer, 0, length);
            bytesAvailable = is.available();

            // bufferSize = Math.min(bytesAvailable, maxBufferSize);

            publishProgress(streamSize, bytesAvailable);
            // Log.v("Progress",""+streamSize+" : "+bytesAvailable);
        }
        // send multipart form data necesssary after file data...
        dos.writeBytes(lineEnd);

        dos.writeBytes(twoHyphens + boundary + lineEnd);
        dos.writeBytes("Content-Disposition: form-data; name=\"data[authentication][email]\""
                + lineEnd);
        dos.writeBytes(lineEnd);
        dos.writeBytes(username);
        dos.writeBytes(lineEnd);
        dos.writeBytes(twoHyphens + boundary + lineEnd);
        dos.writeBytes("Content-Disposition: form-data; name=\"data[authentication][password]\""
                + lineEnd);
        dos.writeBytes(lineEnd);
        dos.writeBytes(enc_password);
        dos.writeBytes(lineEnd);
        dos.writeBytes(twoHyphens + boundary + lineEnd);
        dos.writeBytes("Content-Disposition: form-data; name=\"method\""
                + lineEnd);
        dos.writeBytes(lineEnd);
        dos.writeBytes("uploadWheezeFile");
        dos.writeBytes(lineEnd);
        dos.writeBytes(twoHyphens + boundary + lineEnd);
        dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
        // close streams
        Log.e("Debug", "File is written");

        // Log.v("Conn status", "Disconnected");

    } catch (MalformedURLException ex) {
        ex.printStackTrace();
        Log.e("Debug", "MURLExerror: " + ex.getMessage(), ex);
    } catch (IOException ioe) {
        ioe.printStackTrace();
        Log.e("Debug", "IOEx error: " + ioe.getMessage(), ioe);
        uploadTask.cancel(true);
        return null;
    } finally {
        try {
            is.close();
            dos.flush();
            dos.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    // ------------------ read the SERVER RESPONSE
    try {
        inStream = new DataInputStream(conn.getInputStream());

        if ((jsonResponse = inStream.readLine()) != null) {
            Log.e("Debug", "Server Response " + jsonResponse);

        } else {
            jsonResponse = "";
        }

        inStream.close();
        conn.disconnect();
        //
    } catch (IOException ioex) {
        ioex.printStackTrace();
        Log.e("Debug", "error: " + ioex.getMessage(), ioex);
    }

    return jsonResponse;
}
4

1 回答 1

5

如果接收服务器支持,您可以使用 Content-Range 标头来标识恢复上传。Google-Drive API 支持它。如果你自己动手,我会遵循谷歌使用的模式:

  • 开始上传并获取会话标识符。
  • 上传中断时,请等待互联网可用以恢复。
  • 恢复上传时,首先询问服务器收到了多少字节。(*)
  • 在服务器状态之后的下一个字节继续上传。

(*) 请注意,当我之前推出自己的产品时,我在上传的最后 KB 中添加了来自服务器的编码响应,只是为了验证它在传输过程中没有损坏。但是,在生产中,我从未见过服务器收到损坏数据的情况。

于 2012-12-14T05:14:29.067 回答