これは、ファイルをチャンクでダウンロードすることについての私の質問の続きです。説明はかなり大きいので、いくつかに分けてみます。
1)私がやろうとしたことは?
Window-Phoneアプリケーションのダウンロードマネージャーを作成していました。まず、大きなファイルをダウンロードする問題を解決しようとしました(説明は前の質問にあります)。いいえ、 「再開可能なダウンロード」機能を追加したいと思います。
2)私がすでに行ったこと。
現在、私はうまく機能しているダウンロードマネージャーを持っています。これにより、WindowsPhoneのRAMの制限を超えることができます。このマネージャーの筋書きは、HTTP Rangeヘッダーを使用して、結果的にファイルの小さなチャンクをダウンロードできるようにすることです。
それがどのように機能するかについての簡単な説明:
ファイルは一定サイズのチャンクでダウンロードされます。このサイズを「デルタ」と呼びましょう。ファイルチャンクがダウンロードされた後、それは追加モードでローカルストレージ(ハードディスク、WPでは分離ストレージと呼ばれます)に保存されます(したがって、ダウンロードされたバイト配列は常にファイルの最後に追加されます)。単一のチャンクをダウンロードした後、ステートメント
if (mediaFileLength >= delta) // mediaFileLength is a length of downloaded chunk
チェックされます。それが本当なら、それはダウンロードのために何かが残っていることを意味し、このメソッドは再帰的に呼び出されます。それ以外の場合は、このチャンクが最後であり、ダウンロードするものが残っていないことを意味します。
3)何が問題なのですか?
このロジックを1回限りのダウンロードで使用するまで(つまり、ファイルのダウンロードを開始してダウンロードが完了するまで待つ場合)、これはうまく機能していました。しかし、 「ダウンロード再開」 機能が必要だと思いました。だから、事実:
3.1)ファイルのチャンクサイズは一定であることを私は知っています。
3.2)ファイルが完全にダウンロードされたかどうかはわかります。(これは私のアプリロジックの間接的な結果であり、説明によってあなたを疲れさせることはありません。これが事実であると仮定してください)
これらの2つのステートメントを前提として、ダウンロードされたチャンクの数が (CurrentFileLength)/deltaに等しいことを証明できます。CurrentFileLenghtは、ダウンロード済みのファイルのサイズ(バイト単位)です。
ファイルのダウンロードを再開するには、必要なヘッダーを設定し、ダウンロードメソッドを呼び出すだけです。それは論理のようですね。そして私はそれを実装しようとしました:
// Check file size
using (IsolatedStorageFileStream fileStream = isolatedStorageFile.OpenFile("SomewhereInTheIsolatedStorage", FileMode.Open, FileAccess.Read))
{
int currentFileSize = Convert.ToInt32(fileStream.Length);
int currentFileChunkIterator = currentFileSize / delta;
}
そして、結果として私が見るものは何ですか?ダウンロードされたファイルの長さは2432000バイトです(デルタは304160、合計ファイルサイズは約4.5 MB、ダウンロードしたのは半分だけです)。したがって、結果は約7,995になります。(実際にはlong / int型なので、7であり、代わりに8にする必要があります!)なぜこれが発生するのですか?簡単な計算では、ファイルの長さは2433280である必要があるため、指定された値は非常に近くなりますが、等しくはありません。
さらなる調査により、から与えられたすべての値fileStream.Length
は正確ではないが、すべてが近いことが示されました。
なぜこうなった?正確にはわかりませんが、おそらく.Length値はファイルメタデータのどこかから取得されています。おそらく、このような丸めはこの方法では正常です。おそらく、ダウンロードが中断されたとき、ファイルは完全に保存されていませんでした...(いいえ、それは本当に素晴らしいです、それはできません)
したがって、問題は設定されています-それは「ダウンロードされたチャンクの数を決定する方法」です。問題はそれをどのように解決するかです。
4)問題を解決することについての私の考え。
私の最初の考えは、ここで数学を使うことについてでした。イプシロンネイバーフッドを設定し、ステートメントで使用しcurrentFileChunkIterator = currentFileSize / delta;
ます。しかし、それは私たちにタイプIとタイプIIのエラー(または統計用語が気に入らない場合は誤警報とミス)について覚えておく必要があります。おそらく、ダウンロードするものは何も残っていません。また、提供値と真の値の差が恒久的に大きくなるのか、周期的に変動するのかは確認していません。小さいサイズ(約4-5 MB)では、成長しか見られませんでしたが、それは何も証明していません。
ですから、私は自分の解決策が気に入らないので、ここで助けを求めています。
5)答えとして聞きたいこと:
実際の価値と受け取った価値の違いの原因は何ですか?
真の価値を受け取る方法はありますか?
そうでない場合、私の解決策はこの問題に適していますか?
他にもっと良い解決策はありますか?
PSこの問題がOSに関連しているかどうかわからないため、Windows-Phoneタグを設定しません。分離ストレージツールを使用してダウンロードしたファイルのサイズを確認しましたが、受信した値と同じ値が表示されました(スクリーンショットのロシア語については申し訳ありません)。