簡體   English   中英

將大對象上傳到Cloudfiles返回不同的md5

[英]uploading large object to Cloudfiles returns different md5

所以我有這段代碼,我試圖按照https://github.com/rackspace/php-opencloud/blob/master/docs/userguide/ObjectStore/Storage/Object.md將大文件上傳到Rackspace:

$src_path = 'pathtofile.zip'; //about 700MB
$md5_checksum = md5_file($src_path); //result is f210775ccff9b0e4f686ea49ac4932c2
$trans_opts = array(
      'name' => $md5_checksum,
      'concurrency' => 6,
      'partSize'    => 25000000
 );
$trans_opts['path'] = $src_path;
$transfer = $container->setupObjectTransfer($trans_opts);
$response = $transfer->upload();

據說上傳文件就好了

但是,當我嘗試按照此處的建議下載文件時, 請https://github.com/rackspace/php-opencloud/blob/master/docs/userguide/ObjectStore/USERGUIDE.md

$name = 'f210775ccff9b0e4f686ea49ac4932c2';
$object = $container->getObject($name);
$objectContent = $object->getContent();
$pathtofile = 'destinationpathforfile.zip';
$objectContent->rewind();
$stream = $objectContent->getStream();
file_put_contents($pathtofile, $stream);
$md5 = md5_file($pathtofile);

md5_file的結果最終不同於“ f210775ccff9b0e4f686ea49ac4932c2”。...此外,下載的zip最終無法打開/損壞。

我做錯了什么?

建議您僅對5GB以上的文件使用分段上傳 對於低於此閾值的文件,可以使用常規的uploadObject方法。

使用傳輸構建器時,它將大文件分成較小的段(您提供零件大小),並同時上傳每個文件。 此過程完成后,將創建一個清單文件,其中包含所有這些段的列表。 當您下載清單文件時,它將所有文件整理在一起,從而有效地偽裝成大文件本身。 但這真的是一個組織者。

為了回答您的問題,清單文件的ETag標頭沒有按照您的想法進行計算。 您當前正在做的是獲取整個700MB文件的MD5校驗和,並將其與清單文件的MD5校驗和進行比較。 但是這些沒有可比性。 引用文檔

通過獲取每個段的ETag值,將它們連接在一起,然后返回結果的MD5校驗和,來計算ETag標頭。

使用此DLO操作還有一些缺點,您需要注意:

不能保證端到端的完整性。 最終的一致性模型意味着,盡管您已上傳了細分對象, 但它可能不會立即出現在容器列表中 如果在對象出現在容器中之前下載清單,則該對象將不屬於響應GET請求而返回的內容。

如果您認為傳輸中存在錯誤,則可能是因為HTTP請求一路失敗。 您可以使用重試策略 (使用退避插件)重試失敗的請求。

您還可以打開HTTP日志記錄以檢查每個網絡事務,以幫助調試。 但是,請小心使用以上內容,並將HTTP請求正文(> 25MB)回顯到STDOUT中。 您可能要改用此方法:

use Guzzle\Plugin\Log\LogPlugin;
use Guzzle\Log\ClosureLogAdapter;

$stream = fopen('php://output', 'w');

$logSubscriber = new LogPlugin(new ClosureLogAdapter(function($m) use ($stream) {
    fwrite($stream, $m . PHP_EOL);
}), "# Request:\n{url} {method}\n\n# Response:\n{code} {phrase}\n\n# Connect time: {connect_time}\n\n# Total time: {total_time}", false);

$client->addSubscriber($logSubscriber);

如您所見,您正在使用模板來指示輸出的內容。 有模板變量的完整列表在這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM