src/main/java/com/qingstor/sdk/upload/UploadManager.java
public void putFileMulti(File file, final String objectKey, String fileName, String eTag, final long length) throws QSException {

        if (partSize < 4 * 1024 * 1024) {
            throw new QSException("Every part of the file can not smaller than 4 MB.");
        }

        if (recorder == null || recorder.get(objectKey) == null) {
            Bucket.InitiateMultipartUploadInput inputInit = new Bucket.InitiateMultipartUploadInput();
            Bucket.InitiateMultipartUploadOutput initOutput = bucket.initiateMultipartUpload(objectKey, inputInit);
            int code = initOutput.getStatueCode();
            // Initiate occurs an error.
            if (code < 200 || code >= 300) {
                if (callBack != null) {
                    OutputModel outputModel = new OutputModel();
                    outputModel.setStatueCode(code);
                    outputModel.setMessage(initOutput.getMessage());
                    callBack.onAPIResponse(objectKey, outputModel);
                }
                return;
            }
            uploadModel = new UploadModel();
            uploadModel.setTotalSize(length);
            uploadModel.setUploadID(initOutput.getUploadID());
        } else {
            byte[] bytes = recorder.get(objectKey);
            String json = new String(bytes);
            uploadModel = new Gson().fromJson(json, UploadModel.class);
            // Check status of the task.
            if (uploadModel.isUploadComplete()) {
                if (callBack != null) {
                    OutputModel outputModel = new OutputModel();
                    outputModel.setStatueCode(201);
                    outputModel.setMessage("This task has been uploaded.");
                    callBack.onAPIResponse(objectKey, outputModel);
                }
                return;
            }
        }

        uploadModel.setTotalSize(length);

        // Check if all parts have been completely uploaded.
        if (uploadModel.isFileComplete()) {
            completeMultiUpload(objectKey, fileName, eTag, uploadModel.getUploadID(), length);
        } else {
            for (int i = uploadModel.getCurrentPart(); i < partCounts; i++) {
                // Make records when a new part starts to upload.
                uploadModel.setCurrentPart(i);
                uploadModel.setBytesWritten(i * partSize);
                setData(objectKey, recorder);
                // Request cancelled. Stop upload other parts.
                if (cancellationHandler != null && cancellationHandler.isCancelled()) {
                    // Keep parts data into the upload.
                    setData(objectKey, recorder);
                    break;
                }

                long contentLength = Math.min(partSize, (file.length() - uploadModel.getCurrentPart() * partSize));
                Bucket.UploadMultipartInput input = new Bucket.UploadMultipartInput();
                input.setBodyInputFilePart(file);
                input.setFileOffset(i * partSize);
                input.setContentLength(contentLength);
                input.setPartNumber(i);
                input.setUploadID(uploadModel.getUploadID());

                // Create request to upload a part.
                RequestHandler requestHandler = bucket.uploadMultipartRequest(objectKey, input);

                // Progress listener
                if (progressListener != null) {
                    requestHandler.setProgressListener(new BodyProgressListener() {
                        @Override
                        public void onProgress(long len, long size) {
                            long bytesWritten = uploadModel.getCurrentPart() * partSize + len;
                            progressListener.onProgress(objectKey, bytesWritten, length);
                        }
                    });
                }

                // Cancellation handler.
                requestHandler.setCancellationHandler(cancellationHandler);

                // Sign with server if needed.
                sign(requestHandler);

                // Send the request.
                OutputModel send = requestHandler.send();

                // Check response.
                if (send.getStatueCode() != 200 && send.getStatueCode() != 201) { // Failed.
                    setData(objectKey, recorder);
                    // On upload failed
                    if (callBack != null)
                        callBack.onAPIResponse(objectKey, send);

                    // Once failed, break the circle.
                    break;
                } else if (i == partCounts - 1) { // Success and it is the last part of th file.
                    // Make a record in the upload.
                    uploadModel.setBytesWritten(length);
                    uploadModel.setFileComplete(true);
                    setData(objectKey, recorder);
                }
            }

            // Finally check.
            if (uploadModel.isFileComplete()) {
                completeMultiUpload(objectKey, fileName, eTag, uploadModel.getUploadID(), length);
            }
        }

    }
public void putFileMulti(File file, final String objectKey, String fileName, String eTag, final long length) throws QSException {

        if (partSize < 4 * 1024 * 1024) {
            throw new QSException("Every part of the file can not smaller than 4 MB.");
        }

        if (recorder == null || recorder.get(objectKey) == null) {
            Bucket.InitiateMultipartUploadInput inputInit = new Bucket.InitiateMultipartUploadInput();
            Bucket.InitiateMultipartUploadOutput initOutput = bucket.initiateMultipartUpload(objectKey, inputInit);
            int code = initOutput.getStatueCode();
            // Initiate occurs an error.
            if (code < 200 || code >= 300) {
                if (callBack != null) {
                    OutputModel outputModel = new OutputModel();
                    outputModel.setStatueCode(code);
                    outputModel.setMessage(initOutput.getMessage());
                    callBack.onAPIResponse(objectKey, outputModel);
                }
                return;
            }
            uploadModel = new UploadModel();
            uploadModel.setTotalSize(length);
            uploadModel.setUploadID(initOutput.getUploadID());
        } else {
            byte[] bytes = recorder.get(objectKey);
            String json = new String(bytes);
            uploadModel = new Gson().fromJson(json, UploadModel.class);
            // Check status of the task.
            if (uploadModel.isUploadComplete()) {
                if (callBack != null) {
                    OutputModel outputModel = new OutputModel();
                    outputModel.setStatueCode(201);
                    outputModel.setMessage("This task has been uploaded.");
                    callBack.onAPIResponse(objectKey, outputModel);
                }
                return;
            }
        }

        uploadModel.setTotalSize(length);

        // Check if all parts have been completely uploaded.
        if (uploadModel.isFileComplete()) {
            completeMultiUpload(objectKey, fileName, eTag, uploadModel.getUploadID(), length);
        } else {
            for (int i = uploadModel.getCurrentPart(); i < partCounts; i++) {
                // Make records when a new part starts to upload.
                uploadModel.setCurrentPart(i);
                uploadModel.setBytesWritten(i * partSize);
                setData(objectKey, recorder);
                // Request cancelled. Stop upload other parts.
                if (cancellationHandler != null && cancellationHandler.isCancelled()) {
                    // Keep parts data into the upload.
                    setData(objectKey, recorder);
                    break;
                }

                long contentLength = Math.min(partSize, (file.length() - uploadModel.getCurrentPart() * partSize));
                Bucket.UploadMultipartInput input = new Bucket.UploadMultipartInput();
                input.setBodyInputFilePart(file);
                input.setFileOffset(i * partSize);
                input.setContentLength(contentLength);
                input.setPartNumber(i);
                input.setUploadID(uploadModel.getUploadID());

                // Create request to upload a part.
                RequestHandler requestHandler = bucket.uploadMultipartRequest(objectKey, input);

                // Progress listener
                if (progressListener != null) {
                    requestHandler.setProgressListener(new BodyProgressListener() {
                        @Override
                        public void onProgress(long len, long size) {
                            long bytesWritten = uploadModel.getCurrentPart() * partSize + len;
                            progressListener.onProgress(objectKey, bytesWritten, length);
                        }
                    });
                }

                // Cancellation handler.
                requestHandler.setCancellationHandler(cancellationHandler);

                // Sign with server if needed.
                sign(requestHandler);

                // Send the request.
                OutputModel send = requestHandler.send();

                // Check response.
                if (send.getStatueCode() != 200 && send.getStatueCode() != 201) { // Failed.
                    setData(objectKey, recorder);
                    // On upload failed
                    if (callBack != null)
                        callBack.onAPIResponse(objectKey, send);

                    // Once failed, break the circle.
                    break;
                } else if (i == partCounts - 1) { // Success and it is the last part of th file.
                    // Make a record in the upload.
                    uploadModel.setBytesWritten(length);
                    uploadModel.setFileComplete(true);
                    setData(objectKey, recorder);
                }
            }

            // Finally check.
            if (uploadModel.isFileComplete()) {
                completeMultiUpload(objectKey, fileName, eTag, uploadModel.getUploadID(), length);
            }
        }

    }
Upload a file with a multi upload as a sync request.
@param file file
@param objectKey key of the object in the bucket
@param fileName file name of response(content-disposition) when downloaded
@param eTag MD5 info
@param length length of the file.
@throws QSException exception