@@ -704,9 +704,11 @@ CosResult ObjectOp::MultiUploadObject(const PutObjectByFileReq& req,
704704 }
705705
706706 CosResult upload_result;
707+
708+ uint64_t crc64_origin = 0 ;
707709 upload_result =
708710 MultiThreadUpload (req, resume_uploadid, already_exist_parts, resume_flag,
709- &etags, &part_numbers, handler, change_backup_domain);
711+ &etags, &part_numbers, crc64_origin, handler, change_backup_domain);
710712 // Cancel way
711713 if (handler && !handler->ShouldContinue ()) {
712714 SetResultAndLogError (upload_result, " Request canceled by user" );
@@ -759,16 +761,6 @@ CosResult ObjectOp::MultiUploadObject(const PutObjectByFileReq& req,
759761 // check crc64 if needed
760762 if (req.CheckCRC64 () && comp_result.IsSucc () &&
761763 !comp_resp.GetXCosHashCrc64Ecma ().empty ()) {
762- uint64_t crc64_origin = 0 ;
763- #if defined(_WIN32)
764- if (req.IsWideCharPath ()) {
765- crc64_origin = FileUtil::GetFileCrc64 (req.GetWideCharLocalFilePath ());
766- } else {
767- crc64_origin = FileUtil::GetFileCrc64 (req.GetLocalFilePath ());
768- }
769- #else
770- crc64_origin = FileUtil::GetFileCrc64 (req.GetLocalFilePath ());
771- #endif
772764 uint64_t crc64_server_resp =
773765 StringUtil::StringToUint64 (comp_resp.GetXCosHashCrc64Ecma ());
774766 if (crc64_server_resp != crc64_origin) {
@@ -1704,6 +1696,7 @@ CosResult ObjectOp::MultiThreadUpload(
17041696 const std::vector<std::string>& already_exist_parts, bool resume_flag,
17051697 std::vector<std::string>* etags_ptr,
17061698 std::vector<uint64_t >* part_numbers_ptr,
1699+ uint64_t & crc64_file,
17071700 const SharedTransferHandler& handler,
17081701 bool change_backup_domain) {
17091702 CosResult result;
@@ -1790,6 +1783,7 @@ CosResult ObjectOp::MultiThreadUpload(
17901783
17911784 Poco::ThreadPool tp (pool_size);
17921785
1786+ crc64_file = 0 ;
17931787 // 3. 多线程upload
17941788 {
17951789 uint64_t part_number = 1 ;
@@ -1813,6 +1807,7 @@ CosResult ObjectOp::MultiThreadUpload(
18131807 " , offset=%" PRIu64 " , len=%" PRIu64,
18141808 task_index, file_size, offset, read_len);
18151809
1810+ uint64_t crc64_part = 0 ;
18161811 // Check the resume
18171812 FileUploadTask* ptask = pptaskArr[task_index];
18181813
@@ -1828,11 +1823,25 @@ CosResult ObjectOp::MultiThreadUpload(
18281823 handler->UpdateProgress (read_len);
18291824 }
18301825 } else {
1826+ // 计算每个part的crc64值
1827+ if (req.CheckPartCrc64 ()) {
1828+ crc64_part = CRC64::CalcCRC (crc64_part, static_cast <void *>(file_content_buf[task_index]), read_len);
1829+ }
18311830 FillUploadTask (upload_id, host, path, file_content_buf[task_index],
1832- read_len, part_number, ptask, req.SignHeaderHost ());
1831+ read_len, part_number, ptask, req.SignHeaderHost (), crc64_part );
18331832 tp.start (*ptask);
18341833 }
18351834
1835+ // 根据每个part流式计算整个文件的crc64值
1836+ if (req.CheckCRC64 ()) {
1837+ // 如果已经计算了part的crc64值,只需要直接流式合并即可
1838+ if (crc64_part != 0 ) {
1839+ crc64_file = CRC64::CombineCRC (crc64_file, crc64_part, read_len);
1840+ } else {
1841+ crc64_file = CRC64::CalcCRC (crc64_file, static_cast <void *>(file_content_buf[task_index]), read_len);
1842+ }
1843+ }
1844+
18361845 offset += read_len;
18371846 part_numbers_ptr->push_back (part_number);
18381847 ++part_number;
@@ -1987,8 +1996,10 @@ CosResult ObjectOp::SingleThreadUpload(
19871996 part_number, file_size, offset, read_len);
19881997
19891998 // 提前计算整个文件的crc64,用于整个合并分块完成后做crc64校验
1990- crc64 = CRC64::CalcCRC (crc64, static_cast <void *>(file_content_buf),
1991- static_cast <size_t >(read_len));
1999+ if (req.CheckCRC64 ()) {
2000+ crc64 = CRC64::CalcCRC (crc64, static_cast <void *>(file_content_buf),
2001+ static_cast <size_t >(read_len));
2002+ }
19922003
19932004 // Check the resume
19942005
@@ -2082,7 +2093,8 @@ uint64_t ObjectOp::GetContent(const std::string& src,
20822093void ObjectOp::FillUploadTask (const std::string& upload_id,
20832094 const std::string& host, const std::string& path,
20842095 unsigned char * file_content_buf, uint64_t len,
2085- uint64_t part_number, FileUploadTask* task_ptr, bool sign_header_host) {
2096+ uint64_t part_number, FileUploadTask* task_ptr,
2097+ bool sign_header_host, uint64_t crc64) {
20862098 std::map<std::string, std::string> req_params;
20872099 req_params.insert (std::make_pair (" uploadId" , upload_id));
20882100 req_params.insert (
@@ -2113,6 +2125,7 @@ void ObjectOp::FillUploadTask(const std::string& upload_id,
21132125 task_ptr->AddHeaders (req_headers);
21142126 task_ptr->SetUploadBuf (file_content_buf, len);
21152127 task_ptr->SetPartNumber (part_number);
2128+ task_ptr->SetPartCrc64 (crc64);
21162129}
21172130
21182131void ObjectOp::FillCopyTask (const std::string& upload_id,
0 commit comments