1

だから私はこのコードを持っていて、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 が開けない/破損する

私は何を間違えましたか?

4

1 に答える 1

0

5GB を超えるファイルにはマルチパート アップロードのみを使用することをお勧めします。このしきい値未満のファイルについては、通常のuploadObjectメソッドを使用できます。

転送ビルダーを使用すると、大きなファイルが小さなセグメントに分割され (パーツ サイズを指定)、それぞれが同時にアップロードされます。このプロセスが完了すると、これらすべてのセグメントのリストを含むマニフェスト ファイルが作成されます。マニフェスト ファイルをダウンロードすると、それらがすべてまとめて照合され、効果的に大きなファイルそのものであるかのように装います。しかし、それは本当に主催者です。

質問への回答に戻ると、マニフェスト ファイルの ETag ヘッダーは、あなたが考えているようには計算されません。現在行っていることは、700MB のファイル全体の MD5 チェックサムを取得し、それをマニフェスト ファイルの MD5 チェックサムと比較することです。しかし、これらは比較できません。ドキュメントを引用するには:

ETag ヘッダーは、各セグメントの ETag 値を取得してそれらを連結し、結果の MD5 チェックサムを返すことによって計算されます。

この DLO 操作の使用には、注意が必要な欠点もあります。

エンド ツー エンドの完全性は保証されません。結果整合性モデルとは、セグメント オブジェクトをアップロードしても、すぐにコンテナ リストに表示されない可能性があることを意味します。オブジェクトがコンテナーに表示される前にマニフェストをダウンロードすると、そのオブジェクトは、GET 要求に応答して返されるコンテンツの一部にはなりません。

送信中にエラーが発生したと思われる場合は、途中で HTTP 要求が失敗したことが原因である可能性があります。(backoff プラグインを使用して) 再試行戦略を使用して、失敗した要求を再試行できます

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);

ご覧のとおり、テンプレートを使用して出力内容を指定しています。テンプレート変数の完全なリストはこちらにあります。

于 2014-08-04T09:59:46.087 に答える