@@ -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,18 +761,9 @@ 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 ());
766+ SDK_LOG_DBG (" File Crc64: %" PRIu64, crc64_origin);
774767 if (crc64_server_resp != crc64_origin) {
775768 std::string err_msg =
776769 " MultiUploadObject failed, crc64 check failed, crc64_origin: " +
@@ -1704,6 +1697,7 @@ CosResult ObjectOp::MultiThreadUpload(
17041697 const std::vector<std::string>& already_exist_parts, bool resume_flag,
17051698 std::vector<std::string>* etags_ptr,
17061699 std::vector<uint64_t >* part_numbers_ptr,
1700+ uint64_t & crc64_file,
17071701 const SharedTransferHandler& handler,
17081702 bool change_backup_domain) {
17091703 CosResult result;
@@ -1769,9 +1763,9 @@ CosResult ObjectOp::MultiThreadUpload(
17691763 return result;
17701764 }
17711765
1772- unsigned char ** file_content_buf = new unsigned char * [pool_size];
1766+ PartBufInfo *part_buf_info = new PartBufInfo [pool_size];
17731767 for (int i = 0 ; i < pool_size; ++i) {
1774- file_content_buf [i] = new unsigned char [(size_t )part_size];
1768+ part_buf_info [i]. buf = new unsigned char [(size_t )part_size];
17751769 }
17761770
17771771 std::string dest_url = GetRealUrl (host, path, req.IsHttps ());
@@ -1790,6 +1784,7 @@ CosResult ObjectOp::MultiThreadUpload(
17901784
17911785 Poco::ThreadPool tp (pool_size);
17921786
1787+ crc64_file = 0 ;
17931788 // 3. 多线程upload
17941789 {
17951790 uint64_t part_number = 1 ;
@@ -1802,12 +1797,13 @@ CosResult ObjectOp::MultiThreadUpload(
18021797 }
18031798
18041799 for (; task_index < pool_size; ++task_index) {
1805- fin.read ((char *)file_content_buf [task_index], part_size);
1800+ fin.read ((char *)(part_buf_info [task_index]. buf ) , part_size);
18061801 std::streamsize read_len = fin.gcount ();
18071802 if (read_len == 0 && fin.eof ()) {
18081803 SDK_LOG_DBG (" read over, task_index: %d" , task_index);
18091804 break ;
18101805 }
1806+ part_buf_info[task_index].len = static_cast <size_t >(read_len);
18111807
18121808 SDK_LOG_DBG (" upload data, task_index=%d, file_size=%" PRIu64
18131809 " , offset=%" PRIu64 " , len=%" PRIu64,
@@ -1828,8 +1824,8 @@ CosResult ObjectOp::MultiThreadUpload(
18281824 handler->UpdateProgress (read_len);
18291825 }
18301826 } else {
1831- FillUploadTask (upload_id, host, path, file_content_buf [task_index],
1832- read_len, part_number, ptask, req.SignHeaderHost ());
1827+ FillUploadTask (upload_id, host, path, part_buf_info [task_index]. buf ,
1828+ read_len, part_number, ptask, req.SignHeaderHost (), req. CheckPartCrc64 () );
18331829 tp.start (*ptask);
18341830 }
18351831
@@ -1878,6 +1874,24 @@ CosResult ObjectOp::MultiThreadUpload(
18781874 task_fail_flag = true ;
18791875 break ;
18801876 }
1877+
1878+ // 根据每个part流式计算整个文件的crc64值
1879+ if (req.CheckCRC64 ()) {
1880+ // 如果已经计算了part的crc64值,只需要直接流式合并即可
1881+ if (ptask->GetCrc64Value () != 0 ) {
1882+ crc64_file = CRC64::CombineCRC (crc64_file, ptask->GetCrc64Value (),
1883+ static_cast <uintmax_t >(part_buf_info[task_index].len ));
1884+ SDK_LOG_DBG (" Combine Crc64: %" PRIu64 " , Part Crc64: %" PRIu64,
1885+ crc64_file, ptask->GetCrc64Value ());
1886+ } else {
1887+ // 两种情况都有可能:
1888+ // 1、CheckPartCrc64()为false
1889+ // 2、此part是断点续传已经上传的part
1890+ crc64_file = CRC64::CalcCRC (crc64_file, static_cast <void *>(part_buf_info[task_index].buf ),
1891+ part_buf_info[task_index].len );
1892+ SDK_LOG_DBG (" Calc Crc64: %" PRIu64, crc64_file)
1893+ }
1894+ }
18811895 }
18821896
18831897 if (task_fail_flag) {
@@ -1898,9 +1912,9 @@ CosResult ObjectOp::MultiThreadUpload(
18981912 delete[] pptaskArr;
18991913
19001914 for (int i = 0 ; i < pool_size; ++i) {
1901- delete[] file_content_buf [i];
1915+ delete[] part_buf_info [i]. buf ;
19021916 }
1903- delete[] file_content_buf ;
1917+ delete[] part_buf_info ;
19041918
19051919 return result;
19061920}
@@ -1987,8 +2001,10 @@ CosResult ObjectOp::SingleThreadUpload(
19872001 part_number, file_size, offset, read_len);
19882002
19892003 // 提前计算整个文件的crc64,用于整个合并分块完成后做crc64校验
1990- crc64 = CRC64::CalcCRC (crc64, static_cast <void *>(file_content_buf),
1991- static_cast <size_t >(read_len));
2004+ if (req.CheckCRC64 ()) {
2005+ crc64 = CRC64::CalcCRC (crc64, static_cast <void *>(file_content_buf),
2006+ static_cast <size_t >(read_len));
2007+ }
19922008
19932009 // Check the resume
19942010
@@ -2082,7 +2098,8 @@ uint64_t ObjectOp::GetContent(const std::string& src,
20822098void ObjectOp::FillUploadTask (const std::string& upload_id,
20832099 const std::string& host, const std::string& path,
20842100 unsigned char * file_content_buf, uint64_t len,
2085- uint64_t part_number, FileUploadTask* task_ptr, bool sign_header_host) {
2101+ uint64_t part_number, FileUploadTask* task_ptr,
2102+ bool sign_header_host, bool check_crc64) {
20862103 std::map<std::string, std::string> req_params;
20872104 req_params.insert (std::make_pair (" uploadId" , upload_id));
20882105 req_params.insert (
@@ -2113,6 +2130,7 @@ void ObjectOp::FillUploadTask(const std::string& upload_id,
21132130 task_ptr->AddHeaders (req_headers);
21142131 task_ptr->SetUploadBuf (file_content_buf, len);
21152132 task_ptr->SetPartNumber (part_number);
2133+ task_ptr->SetCheckCrc64 (check_crc64);
21162134}
21172135
21182136void ObjectOp::FillCopyTask (const std::string& upload_id,
0 commit comments