デスクトップアプリケーションからサーバーに、潜在的に大きな (数十から数百メガバイトのような) ファイルをアップロードする必要があります。サーバー コードは、C++/MFC のデスクトップ アプリケーションである PHP で記述されています。このソフトウェアは信頼性の低い接続で使用されるため、アップロードが途中で失敗したときにファイルのアップロードを再開できるようにしたいと考えています。私のオプションは何ですか?http://www.chilkatsoft.com/refdoc/vcCkUploadRef.htmlなど、C++ 用の HTTP アップロード コンポーネントを多数見つけました。これは素晴らしいように見えますが、半分完了したアップロードの「再開」を処理していないようです (これは、HTTP 1.1 がサポートしていないためだと思います)。BITS サービスも調べましたが、アップロードには IIS サーバーが必要です。これまでのところ、私の唯一のオプションは、アップロードしたいファイルを小さな断片 (それぞれ 1 メガなど) に分割し、それらすべてをサーバーにアップロードし、PHP で再構築し、チェックサムを実行してすべてがうまくいったかどうかを確認することです。再開するには、アップロードの開始時になんらかの形式の「ハンドシェイク」を行って、どの部分が既にサーバー上にあるかを確認する必要があります。これを手動でコーディングする必要がありますか、またはこれをすべて実行するライブラリ、またはまったく異なるソリューションを知っている人はいますか? 私'
9 に答える
8 か月遅れましたが、たまたまこの質問に出くわし、webDAV が言及されていないことに驚きました。HTTP PUT メソッドを使用してアップロードし、Content-Range ヘッダーを含めて再開などを処理できます。HEAD リクエストは、ファイルが既に存在するかどうかと、その大きさを教えてくれます。したがって、おそらく次のようなものです。
1) リモートファイルの HEAD
2) 存在し、サイズ == ローカル サイズの場合、アップロードは既に行われています
3) サイズ < ローカル サイズの場合は、ローカル ファイル内の適切な場所を要求してシークする Content-Range ヘッダーを追加します。
4) ファイル (再開する場合はファイルの一部) をアップロードするための PUT 要求を作成します。
5) PUT リクエスト中に接続に失敗した場合は、手順 1 からやり直します
また、ファイルの一覧表示 (PROPFIND) と名前の変更 (MOVE)、および dav を使用したディレクトリの作成 (MKCOL) もできます。
Apache と Lighttpd の両方に dav 拡張機能があると思います。
標準サイズ (たとえば 256k) が必要です。ユーザー x によってアップロードされたファイル「abc.txt」が 78.3MB の場合、313 個の完全なチャンクと 1 個の小さなチャンクになります。
- ファイル名とサイズ、および初期スレッド数を指定して、アップロードのリクエストを送信します。
- PHPコードは、IPアドレスとファイル名にちなんで名付けられた一時フォルダーを作成します。
- その後、アプリは複数の接続を使用して異なるスレッドでデータを送信できるため、チャンク 1,111,212,313 を同時に (個別のチェックサムで) 送信できます。
- あなたのphpコードはそれらを別のファイルに保存し、チェックサムを検証した後に受信を確認し、送信するか、このスレッドで停止する新しいチャンクの数を指定します.
- すべてのスレッドが終了したら、php にすべてのファイルを結合するように依頼します。何か不足している場合は、3 に進みます。
アプリが送信を制御しているため、スレッドの数を自由に増減できます。
単純な進行状況バー、または downthemall のチャンクの詳細ビューに近いもののいずれかで、進行状況インジケーターを簡単に表示できます。
libcurl (C api) は実行可能なオプションになる可能性があります
-C/--continue-at 指定されたオフセットで以前のファイル転送を続行/再開します。指定されたオフセットは、宛先に転送される前にソース ファイルの先頭から数えて、スキップされる正確なバイト数です。アップロードで使用する場合、curl は FTP サーバー コマンド SIZE を使用しません。「-C -」を使用して、curl に転送を再開する場所/方法を自動的に見つけるように指示します。次に、指定された出力/入力ファイルを使用してそれを把握します。このオプションを複数回使用すると、最後のオプションが使用されます
おそらく最も簡単な方法は、 http://yourpage/.../upload.php?file=myfile&from=123456のようにファイル名と範囲をパラメーターとして受け入れ、クライアントで履歴書を処理するアップロード ページを作成することです (おそらくサーバーが受信した範囲を検査する関数を追加できます)
プロセス全体を逆にすることはオプションですか? つまり、ファイルをサーバーにプッシュする代わりに、標準の HTTP GET を使用してサーバーにファイルをプルさせ、すべてのオプション (accept-ranges など) を使用します。
@ Anton Gogolev Lol、私はちょうど同じことを考えていました-すべてを逆にして、サーバーをクライアントにし、クライアントをサーバーにします。なぜそれがうまくいかないのか、ロエルに感謝します。
@ Roel Java アップローダーを実装することをお勧めします [JumpLoader は優れており、JScript インターフェイスとサンプル PHP サーバー側コードさえ備えています]。Flash アップローダは、BIIIGGG ファイルに関してはひどく苦しんでいます :) 、つまりギガバイト規模です。
F*EX は、HTTP 経由で最大 TB 範囲のファイルをアップロードでき、リンク障害後に再開できます。これは Perl で書かれており、UNIX ベースのサーバーを必要とするため、ニーズを正確に満たすものではありませんが、クライアントは任意のオペレーティング システム上にある可能性があります。それでも役立つかもしれません: http://fex.rus.uni-stuttgart.de/