public void run() { int offset = recoveryFromRecord(); try { file = new RandomAccessFile(f, "r"); } catch (FileNotFoundException e) { e.printStackTrace(); completionHandler.complete(key, ResponseInfo.fileError(e), null); return; } nextTask(offset, 0, config.up.address); }
/** * 创建块,并上传第一个分片内容 * * @param address 上传主机 * @param offset 本地文件偏移量 * @param blockSize 分块的块大小 * @param chunkSize 分片的片大小 * @param progress 上传进度 * @param _completionHandler 上传完成处理动作 */ private void makeBlock( URI address, int offset, int blockSize, int chunkSize, ProgressHandler progress, CompletionHandler _completionHandler, UpCancellationSignal c) { String path = format(Locale.ENGLISH, "/mkblk/%d", blockSize); try { file.seek(offset); file.read(chunkBuffer, 0, chunkSize); } catch (IOException e) { completionHandler.complete(key, ResponseInfo.fileError(e), null); return; } this.crc32 = Crc32.bytes(chunkBuffer, 0, chunkSize); URI u = newURI(address, path); post(u, chunkBuffer, 0, chunkSize, progress, _completionHandler, c); }
private void putChunk( URI address, int offset, int chunkSize, String context, ProgressHandler progress, CompletionHandler _completionHandler, UpCancellationSignal c) { int chunkOffset = offset % Configuration.BLOCK_SIZE; String path = format(Locale.ENGLISH, "/bput/%s/%d", context, chunkOffset); try { file.seek(offset); file.read(chunkBuffer, 0, chunkSize); } catch (IOException e) { completionHandler.complete(key, ResponseInfo.fileError(e), null); return; } this.crc32 = Crc32.bytes(chunkBuffer, 0, chunkSize); URI u = newURI(address, path); post(u, chunkBuffer, 0, chunkSize, progress, _completionHandler, c); }
private boolean isNotQiniu(ResponseInfo info) { return info.isNotQiniu() && !token.hasReturnUrl(); }
private void nextTask(final int offset, final int retried, final URI address) { if (isCancelled()) { ResponseInfo i = ResponseInfo.cancelled(); completionHandler.complete(key, i, null); return; } if (offset == size) { CompletionHandler complete = new CompletionHandler() { @Override public void complete(ResponseInfo info, JSONObject response) { if (info.isOK()) { removeRecord(); options.progressHandler.progress(key, 1.0); completionHandler.complete(key, info, response); return; } if ((isNotQiniu(info) || info.needRetry()) && retried < config.retryMax) { nextTask(offset, retried + 1, config.upBackup.address); return; } completionHandler.complete(key, info, response); } }; makeFile(address, complete, options.cancellationSignal); return; } final int chunkSize = calcPutSize(offset); ProgressHandler progress = new ProgressHandler() { @Override public void onProgress(int bytesWritten, int totalSize) { double percent = (double) (offset + bytesWritten) / size; if (percent > 0.95) { percent = 0.95; } options.progressHandler.progress(key, percent); } }; CompletionHandler complete = new CompletionHandler() { @Override public void complete(ResponseInfo info, JSONObject response) { if (!info.isOK()) { if (info.statusCode == 701 && retried < config.retryMax) { nextTask( (offset / Configuration.BLOCK_SIZE) * Configuration.BLOCK_SIZE, retried + 1, address); return; } if ((isNotQiniu(info) || info.needRetry()) && retried < config.retryMax) { nextTask(offset, retried + 1, config.upBackup.address); return; } completionHandler.complete(key, info, response); return; } String context = null; if (response == null && retried < config.retryMax) { nextTask(offset, retried + 1, config.upBackup.address); return; } long crc = 0; try { context = response.getString("ctx"); crc = response.getLong("crc32"); } catch (JSONException e) { e.printStackTrace(); } if ((context == null || crc != ResumeUploader.this.crc32) && retried < config.retryMax) { nextTask(offset, retried + 1, config.upBackup.address); return; } contexts[offset / Configuration.BLOCK_SIZE] = context; record(offset + chunkSize); nextTask(offset + chunkSize, retried, address); } }; if (offset % Configuration.BLOCK_SIZE == 0) { int blockSize = calcBlockSize(offset); makeBlock( address, offset, blockSize, chunkSize, progress, complete, options.cancellationSignal); return; } String context = contexts[offset / Configuration.BLOCK_SIZE]; putChunk(address, offset, chunkSize, context, progress, complete, options.cancellationSignal); }