|
|
@@ -10,7 +10,6 @@ import cn.reghao.jutil.jdk.serializer.JsonConverter;
|
|
|
import cn.reghao.jutil.tool.http.DefaultWebRequest;
|
|
|
import cn.reghao.oss.api.rest.UploadFilePart;
|
|
|
import cn.reghao.oss.api.rest.UploadFileRet;
|
|
|
-import cn.reghao.oss.api.rest.UploadPrepareRet;
|
|
|
import cn.reghao.oss.api.rest.UploadedPart;
|
|
|
import com.google.gson.reflect.TypeToken;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
@@ -45,28 +44,29 @@ public class ObjectMultipartUploadService {
|
|
|
this.token = token;
|
|
|
}
|
|
|
|
|
|
- public UploadPrepareRet create(File file) throws Exception {
|
|
|
- String filename = file.getName();
|
|
|
- long len = file.length();
|
|
|
+ /**
|
|
|
+ * 获取已上传的分片文件
|
|
|
+ *
|
|
|
+ * @param
|
|
|
+ * @return
|
|
|
+ * @date 2024-10-29 15:43:46
|
|
|
+ */
|
|
|
+ public UploadedPart getUploadedParts(File file, int channelId) throws Exception {
|
|
|
String sha256sum = DigestUtil.sha256sum(file.getAbsolutePath());
|
|
|
-
|
|
|
MultiPartBodyPublisher publisher = new MultiPartBodyPublisher();
|
|
|
- publisher.addPart("filename", filename)
|
|
|
- .addPart("size", ""+len)
|
|
|
- .addPart("sha256sum", sha256sum);
|
|
|
+ publisher.addPart("sha256sum", sha256sum);
|
|
|
|
|
|
- String api = endpoint + "/?create";
|
|
|
+ String api = endpoint + "/?multiparts";
|
|
|
HttpRequest httpRequest = HttpRequest.newBuilder(new URI(api))
|
|
|
.version(HttpClient.Version.HTTP_1_1)
|
|
|
- .header("Authorization", "Bearer " + token)
|
|
|
- .header("Content-Type", "multipart/form-data; boundary=" + publisher.getBoundary())
|
|
|
- .POST(publisher.build())
|
|
|
+ .header("Authorization", token)
|
|
|
+ .GET()
|
|
|
.build();
|
|
|
|
|
|
HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
|
|
|
String body = httpResponse.body();
|
|
|
- Type type = new TypeToken<WebResult<UploadPrepareRet>>(){}.getType();
|
|
|
- WebResult<UploadPrepareRet> webResult = JsonConverter.jsonToObject(body, type);
|
|
|
+ Type type = new TypeToken<WebResult<UploadedPart>>(){}.getType();
|
|
|
+ WebResult<UploadedPart> webResult = JsonConverter.jsonToObject(body, type);
|
|
|
if (webResult.getCode() != 0) {
|
|
|
String errMsg = webResult.getMsg();
|
|
|
return null;
|
|
|
@@ -75,32 +75,73 @@ public class ObjectMultipartUploadService {
|
|
|
return webResult.getData();
|
|
|
}
|
|
|
|
|
|
- public UploadedPart get(File file) throws Exception {
|
|
|
- //String sha256sum = DigestUtil.sha256sum(file.getAbsolutePath());
|
|
|
- String sha256sum = "";
|
|
|
- MultiPartBodyPublisher publisher = new MultiPartBodyPublisher();
|
|
|
- publisher
|
|
|
- .addPart("sha256sum", sha256sum);
|
|
|
+ /**
|
|
|
+ * 分片上传大文件
|
|
|
+ *
|
|
|
+ * @param
|
|
|
+ * @return
|
|
|
+ * @date 2024-10-29 15:44:13
|
|
|
+ */
|
|
|
+ public UploadFileRet uploadFilePart(File file, int channelId) throws Exception {
|
|
|
+ String identifier = DigestUtil.sha256sum(new FileInputStream(file));
|
|
|
+ String filename = file.getName();
|
|
|
+ String relativePath = file.getAbsolutePath();
|
|
|
|
|
|
- String api = endpoint + "/?get_multipart";
|
|
|
- HttpRequest httpRequest = HttpRequest.newBuilder(new URI(api))
|
|
|
- .version(HttpClient.Version.HTTP_1_1)
|
|
|
- .header("Authorization", token)
|
|
|
- .header("Content-Type", "multipart/form-data; boundary=" + publisher.getBoundary())
|
|
|
- .POST(publisher.build())
|
|
|
- //.GET()
|
|
|
- .build();
|
|
|
+ long totalSize = file.length();
|
|
|
+ // 分片大小在 10MB - 100MB 之间,只有最后一个分片才允许小于 10MB(这无法避免)
|
|
|
+ long chunkSize = fileSplitter.getPartSize();
|
|
|
+ long totalChunks = totalSize/chunkSize;
|
|
|
+ if (totalSize % chunkSize != 0) {
|
|
|
+ totalChunks += 1;
|
|
|
+ }
|
|
|
|
|
|
- HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
|
|
|
- String body = httpResponse.body();
|
|
|
- Type type = new TypeToken<WebResult<UploadedPart>>(){}.getType();
|
|
|
- WebResult<UploadedPart> webResult = JsonConverter.jsonToObject(body, type);
|
|
|
- if (webResult.getCode() != 0) {
|
|
|
- String errMsg = webResult.getMsg();
|
|
|
- return null;
|
|
|
+ Map<Integer, Long> map = new HashMap<>();
|
|
|
+ List<Integer> failedChunkNumbers = new ArrayList<>();
|
|
|
+ for (int i = 0; i < totalChunks; i++) {
|
|
|
+ long start = i*chunkSize;
|
|
|
+ // 从 start 位置开始读取 chunkSize 的数据
|
|
|
+ byte[] part = fileSplitter.getPart(file.getAbsolutePath(), start);
|
|
|
+ int chunkNumber = i + 1;
|
|
|
+ map.put(chunkNumber, start);
|
|
|
+
|
|
|
+ int currentChunkSize = part.length;
|
|
|
+ UploadFilePart uploadFilePart = new UploadFilePart(channelId, identifier, filename, relativePath,
|
|
|
+ totalSize, chunkSize, totalChunks, chunkNumber, currentChunkSize);
|
|
|
+
|
|
|
+ UploadFileRet uploadFileRet = postObject(part, uploadFilePart);
|
|
|
+ if (uploadFileRet == null) {
|
|
|
+ log.info("{}:{} upload failed", chunkNumber, currentChunkSize);
|
|
|
+ failedChunkNumbers.add(chunkNumber);
|
|
|
+ } else {
|
|
|
+ log.info("{}:{} uploaded {} bytes", totalChunks, chunkNumber, currentChunkSize);
|
|
|
+ if (uploadFileRet.isMerged()) {
|
|
|
+ return uploadFileRet;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- return webResult.getData();
|
|
|
+ // 重传上传失败的文件分片
|
|
|
+ if (!failedChunkNumbers.isEmpty()) {
|
|
|
+ for (int chunkNumber : failedChunkNumbers) {
|
|
|
+ long start = map.get(chunkNumber);
|
|
|
+ byte[] part = fileSplitter.getPart(file.getAbsolutePath(), start);
|
|
|
+ int currentChunkSize = part.length;
|
|
|
+ UploadFilePart uploadFilePart = new UploadFilePart(channelId, identifier, filename, relativePath,
|
|
|
+ totalSize, chunkSize, totalChunks, chunkNumber, currentChunkSize);
|
|
|
+
|
|
|
+ UploadFileRet uploadFileRet = postObject(part, uploadFilePart);
|
|
|
+ if (uploadFileRet == null) {
|
|
|
+ log.info("{}:{} upload failed", chunkNumber, currentChunkSize);
|
|
|
+ } else {
|
|
|
+ log.info("{}:{} uploaded {} bytes", totalChunks, chunkNumber, currentChunkSize);
|
|
|
+ if (uploadFileRet.isMerged()) {
|
|
|
+ return uploadFileRet;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -173,66 +214,4 @@ public class ObjectMultipartUploadService {
|
|
|
|
|
|
return webResult.getData();
|
|
|
}
|
|
|
-
|
|
|
- public UploadFileRet upload(File file, int channelId) throws Exception {
|
|
|
- String identifier = DigestUtil.sha256sum(new FileInputStream(file));
|
|
|
- String filename = file.getName();
|
|
|
- String relativePath = file.getAbsolutePath();
|
|
|
-
|
|
|
- long totalSize = file.length();
|
|
|
- // 分片大小在 10MB - 100MB 之间,只有最后一个分片才允许小于 10MB(这无法避免)
|
|
|
- long chunkSize = fileSplitter.getPartSize();
|
|
|
- long totalChunks = totalSize/chunkSize;
|
|
|
- if (totalSize % chunkSize != 0) {
|
|
|
- totalChunks += 1;
|
|
|
- }
|
|
|
-
|
|
|
- Map<Integer, Long> map = new HashMap<>();
|
|
|
- List<Integer> failedChunkNumbers = new ArrayList<>();
|
|
|
- for (int i = 0; i < totalChunks; i++) {
|
|
|
- long start = i*chunkSize;
|
|
|
- // 从 start 位置开始读取 chunkSize 的数据
|
|
|
- byte[] part = fileSplitter.getPart(file.getAbsolutePath(), start);
|
|
|
- int chunkNumber = i + 1;
|
|
|
- map.put(chunkNumber, start);
|
|
|
-
|
|
|
- int currentChunkSize = part.length;
|
|
|
- UploadFilePart uploadFilePart = new UploadFilePart(channelId, identifier, filename, relativePath,
|
|
|
- totalSize, chunkSize, totalChunks, chunkNumber, currentChunkSize);
|
|
|
-
|
|
|
- UploadFileRet uploadFileRet = postObject(part, uploadFilePart);
|
|
|
- if (uploadFileRet == null) {
|
|
|
- log.info("{}:{} upload failed", chunkNumber, currentChunkSize);
|
|
|
- failedChunkNumbers.add(chunkNumber);
|
|
|
- } else {
|
|
|
- log.info("{}:{} uploaded {} bytes", totalChunks, chunkNumber, currentChunkSize);
|
|
|
- if (uploadFileRet.isMerged()) {
|
|
|
- return uploadFileRet;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 重传上传失败的文件分片
|
|
|
- if (!failedChunkNumbers.isEmpty()) {
|
|
|
- for (int chunkNumber : failedChunkNumbers) {
|
|
|
- long start = map.get(chunkNumber);
|
|
|
- byte[] part = fileSplitter.getPart(file.getAbsolutePath(), start);
|
|
|
- int currentChunkSize = part.length;
|
|
|
- UploadFilePart uploadFilePart = new UploadFilePart(channelId, identifier, filename, relativePath,
|
|
|
- totalSize, chunkSize, totalChunks, chunkNumber, currentChunkSize);
|
|
|
-
|
|
|
- UploadFileRet uploadFileRet = postObject(part, uploadFilePart);
|
|
|
- if (uploadFileRet == null) {
|
|
|
- log.info("{}:{} upload failed", chunkNumber, currentChunkSize);
|
|
|
- } else {
|
|
|
- log.info("{}:{} uploaded {} bytes", totalChunks, chunkNumber, currentChunkSize);
|
|
|
- if (uploadFileRet.isMerged()) {
|
|
|
- return uploadFileRet;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return null;
|
|
|
- }
|
|
|
}
|