トレントに穴を開けてスペースを解放し、配布を続けます(パート1)

画像

警告:このグラフは、まだ取り上げていない記事の第2部のスクリプト用に作成されています。 したがって、その中のデータに注意を払ってはいけません。 この記事のグラフは最後にあります。







この記事の情報は自己責任で使用してください。 ファイルからデータを消去します。 この記事は、WindowsオペレーティングシステムとNTFSファイルシステムについて書かれています。 記事には多くの画像もあります。







スパースファイルとは



スパースファイルは、ゼロバイトのシーケンス[1]がこれらのシーケンスに関する情報(ホールのリスト)に置き換えられたファイルです。



ホールとは、ディスクに書き込まれないファイル内のゼロバイトのシーケンスです。 ホールに関する情報(バイト単位のファイルの先頭からのオフセットとバイト数)は、FSメタデータに格納されます。

また、Geektimesに関する短い記事「 NTFSのスパースファイル 」もあります







オペレーティングシステムは、デフォルトではスパースファイルを作成しません。 このフラグは、プログラムで、またはユーティリティを使用してファイルに設定できます。







ユーティリティを使用してフラグを設定します。







fsutil sparse setflag < >
      
      





プログラムで(C ++ Windows):







 DeviceIoControl( m_hFile, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &dwOut, NULL )
      
      





ファイル内のシーケンスを自動的にゼロにしても、ディスク容量が解放されることはありません。これは、プログラムまたはユーティリティを使用して行う必要もあります。







ユーティリティヘルプファイルのゼロ:







 fsutil sparse setrange < > <> <>
      
      





プログラムで(C ++ Windows):







 FILE_ZERO_DATA_INFORMATION range; range.FileOffset.QuadPart = start; range.BeyondFinalZero.QuadPart = start + size; DeviceIoControl( m_hFile, FSCTL_SET_ZERO_DATA, &range, sizeof(range), NULL, 0, &dwOut, NULL );
      
      





シンプルなファイル



それらのために、ファイル内のスペースを解放する特別なユーティリティがあります。これにより、ゼロの大きなシーケンスが破損することなくゼロになります。 しかし、そのようなファイルはまれです。







ダウンロード可能なファイル



  1. スパースフラグを使用すると、ファイルはロードされたデータが必要とする量を占有します。 これは、ダウンロードキューに多くのファイルがあり、それらの合計サイズが使用可能なサイズを超える場合に役立ちます。
  2. パーツのハッシュにより、ゼロで満たされたパーツを判別し、すでにロード済みとしてマークできます。 これらの部品はロードされず、ディスク容量を占有しません。







    トレントで空のピースを見つけるための関数(C ++ Shareaza)

    BTInfo.cpp







     BOOL CBTInfo::IsZeroBlock(uint32 nBlock) const { static const uint32 ZeroHash[22][5] = { // Hash: 897256B6709E1A4DA9DABA92B6BDE39CCFCCD8C1 Size: 16384 { 0xB6567289, 0x4D1A9E70, 0x92BADAA9, 0x9CE3BDB6, 0xC1D8CCCF }, // Hash: 5188431849B4613152FD7BDBA6A3FF0A4FD6424B Size: 32768 { 0x18438851, 0x3161B449, 0xDB7BFD52, 0x0AFFA3A6, 0x4B42D64F }, // Hash: 1ADC95BEBE9EEA8C112D40CD04AB7A8D75C4F961 Size: 65536 { 0xBE95DC1A, 0x8CEA9EBE, 0xCD402D11, 0x8D7AAB04, 0x61F9C475 }, // Hash: 67DFD19F3EB3649D6F3F6631E44D0BD36B8D8D19 Size: 131072 { 0x9FD1DF67, 0x9D64B33E, 0x31663F6F, 0xD30B4DE4, 0x198D8D6B }, // Hash: 2E000FA7E85759C7F4C254D4D9C33EF481E459A7 Size: 262144 { 0xA70F002E, 0xC75957E8, 0xD454C2F4, 0xF43EC3D9, 0xA759E481 }, // Hash: 6A521E1D2A632C26E53B83D2CC4B0EDECFC1E68C Size: 524288 { 0x1D1E526A, 0x262C632A, 0xD2833BE5, 0xDE0E4BCC, 0x8CE6C1CF }, // Hash: 3B71F43FF30F4B15B5CD85DD9E95EBC7E84EB5A3 Size: 1048576 { 0x3FF4713B, 0x154B0FF3, 0xDD85CDB5, 0xC7EB959E, 0xA3B54EE8 }, // Hash: 7D76D48D64D7AC5411D714A4BB83F37E3E5B8DF6 Size: 2097152 { 0x8DD4767D, 0x54ACD764, 0xA414D711, 0x7EF383BB, 0xF68D5B3E }, // Hash: 2BCCBD2F38F15C13EB7D5A89FD9D85F595E23BC3 Size: 4194304 { 0x2FBDCC2B, 0x135CF138, 0x895A7DEB, 0xF5859DFD, 0xC33BE295 }, // Hash: 5FDE1CCE603E6566D20DA811C9C8BCCCB044D4AE Size: 8388608 { 0xCE1CDE5F, 0x66653E60, 0x11A80DD2, 0xCCBCC8C9, 0xAED444B0 }, // Hash: 3B4417FC421CEE30A9AD0FD9319220A8DAE32DA2 Size: 16777216 { 0xFC17443B, 0x30EE1C42, 0xD90FADA9, 0xA8209231, 0xA22DE3DA }, // Hash: 57B587E1BF2D09335BDAC6DB18902D43DFE76449 Size: 33554432 { 0xE187B557, 0x33092DBF, 0xDBC6DA5B, 0x432D9018, 0x4964E7DF }, // Hash: 44FAC4BEDDE4DF04B9572AC665D3AC2C5CD00C7D Size: 67108864 { 0xBEC4FA44, 0x04DFE4DD, 0xC62A57B9, 0x2CACD365, 0x7D0CD05C }, // Hash: BA713B819C1202DCB0D178DF9D2B3222BA1BBA44 Size: 134217728 { 0x813B71BA, 0xDC02129C, 0xDF78D1B0, 0x22322B9D, 0x44BA1BBA }, // Hash: 7B91DBDC56C5781EDF6C8847B4AA6965566C5C75 Size: 268435456 { 0xDCDB917B, 0x1E78C556, 0x47886CDF, 0x6569AAB4, 0x755C6C56 }, // Hash: 5B088492C9F4778F409B7AE61477DEC124C99033 Size: 536870912 { 0x9284085B, 0x8F77F4C9, 0xE67A9B40, 0xC1DE7714, 0x3390C924 }, // Hash: 2A492F15396A6768BCBCA016993F4B4C8B0B5307 Size: 1073741824 { 0x152F492A, 0x68676A39, 0x16A0BCBC, 0x4C4B3F99, 0x07530B8B }, // Hash: 91D50642DD930E9542C39D36F0516D45F4E1AF0D Size: 2147483648 { 0x4206D591, 0x950E93DD, 0x369DC342, 0x456D51F0, 0x0DAFE1F4 }, // Hash: 1BF99EE9F374E58E201E4DDA4F474E570EB77229 Size: 4294967296 { 0xE99EF91B, 0x8EE574F3, 0xDA4D1E20, 0x574E474F, 0x2972B70E }, // Hash: BCC8C0CA9E402EEE924A6046966D18B1F66EB577 Size: 8589934592 { 0xCAC0C8BC, 0xEE2E409E, 0x46604A92, 0xB1186D96, 0x77B56EF6 }, // Hash: DC44DD38511BD6D1233701D63C15B87D0BD9F3A5 Size: 17179869184 { 0x38DD44DC, 0xD1D61B51, 0xD6013723, 0x7DB8153C, 0xA5F3D90B }, // Hash: 7FFB233B3B2806328171FB8B5C209F48DC095B72 Size: 34359738368 { 0x3B23FB7F, 0x3206283B, 0x8BFB7181, 0x489F205C, 0x725B09DC } }; int i = 0; for(; m_nBlockSize > ( (uint64) 16384 << i ); i++) if ( i > 21 ) return FALSE; return memcmp( &m_pBlockBTH[ nBlock ], ZeroHash[ i ], sizeof( ZeroHash[ i ] ) ) == 0; }
          
          









短所:







ファイルは断片化されています。 これは通常のファイルでも発生しますが、スパースファイルではより顕著になります。 ファイルはランダムにダウンロードされ、必要に応じてデータ用のスペースが割り当てられます。 ファイルの断片はディスク全体に散らばっています。







ディストリビューション上の不要なファイルの部分的な消去。



スパースファイルを使用すると、他のデータ用の領域を徐々に解放できます。 fsutil sparse setrange



指定されたセクションfsutil sparse setrange



解放され、ゼロからのみ読み取られます。







これらのファイルを再確認すると、クライアントは間引きセクションをロードされていないものとしてマークし(最初にゼロがなかった場合)、それらを配布しません。 彼がそれらを再びダウンロードしようとしないように、ダウンロードボックスのチェックを外す必要があります。 この場合、ファイルのセクション全体がswarmで使用可能のままになります。







メリット:







  1. したがって、新しいトレントをダウンロードするために十分なスペースを解放しながら、ディストリビューションにとどまることができます。
  2. ディストリビューションに残り、他のソースへの負荷は増加しません。
  3. 配布するソースが多いほど、ダウンロード速度は速くなります。




スクリーンショットットqBittorent







ファイル「linux.iso」があります。 そのサイズは1.4ギガバイトです。 新規ダウンロードの場合、1ギガバイトの十分な空きディスク容量がありません。







fsutil sparseを直接使用する(正しくない!)



 fsutil sparse setflag linux.iso fsutil sparse setrange linux.iso 0 1073741824
      
      





1ギガバイトのディスク領域を解放しましたが、この方法でファイルの先頭にある大きな連続した部分をクリアします。 他のソースがこれを繰り返すと、ファイルの最後に利用可能な部分が過剰になり、完全なソースがないとその先頭に完全にアクセスできなくなる可能性があります。







ランダムな位置を選択する簡単なスクリプトを書きます



大きい数値が使用されるため、便宜上JavaScriptで計算を実行します







sparse_light.js







 //     if (WScript.Arguments.Length == 2) { //     var file_size = parseInt( WScript.Arguments.Item(0) ); //        var sparse_size = parseInt( WScript.Arguments.Item(1) ); if ( file_size > 0 && sparse_size > 0 && sparse_size < file_size ) { //        if ( file_size / 2 > sparse_size ) //               WScript.Echo( Math.round( ( file_size - sparse_size ) * Math.random() ), sparse_size ); else { //              var data_size = file_size - sparse_size; var data_pos = Math.round( ( file_size - data_size ) * Math.random() ); //      if ( data_pos > 0 ) WScript.Echo( 0, data_pos ); var sparse_pos = data_pos + data_size; //      if ( sparse_pos < file_size ) WScript.Echo( sparse_pos, file_size - sparse_pos ); } } }
      
      





ファイルサイズの取得とfsutil sparseの操作は、バッチファイルに残ります。







sparse_light.cmd







 @rem %1        @rem %2       @setlocal @rem        @echo This script will erase some of the data (%2 bytes) from the file: %1 @set /P AREYOUSURE=Are you sure (Y/[N])? @if /I "%AREYOUSURE%" NEQ "Y" goto END @rem     fsutil sparse setflag %1 @rem          sparse_light.js      for /f "tokens=1,2" %%i in ('cscript //nologo "%~dp0sparse_light.js" %~z1 %2') do ( fsutil sparse setrange %1 %%i %%j ) :END @endlocal
      
      





私たちは電話します:







 sparse_random.cmd linux.iso 1073741824
      
      





このスクリプトは、ファイルの1つまたは2つのランダムセクションを上書きします。 このスクリプトは、単一のファイルを上書きするのに適しています。







qBittorentでスクリプトを使用する例(多くのスクリーンショット)



  1. qBittorentを開く

    スクリーンショットットqBittorent
  2. 目的のトレント(この場合はlinux.iso)を選択します。 コンテキストメニューを呼び出し、[一時停止]をクリックします。

    BクリンスショットqBittorent。コンテキストメニューが開き、一時停止が選択されました。
  3. スクリプトを使用してファイルを切り取ります。

    sparse_light.cmd G:\linux\linux.iso 500000000





    スクリプトの実行結果が表示されますcmd.exeウィンドウのスクリーショント
  4. 指定された量のディスク領域を必ず解放します。 ファイルのプロパティを開き、「サイズ」と「ディスク上のサイズ」を比較します。

    ファルプロパティウィンドウ
  5. qBittorentでは、コンテンツタブに切り替えます

    [コンテンツ]タブ。ファイルの横にチェックマークがあります
  6. ファイルの横にあるチェックボックスをオフにして、検証後に再びロードが開始されないようにします

    [コンテンツ]タブ。ファイルの横にあるチェェククマーがオフになていますす
  7. ディストリビューションを右クリックしてコンテキストメニューを呼び出し、「強制チェック」項目をクリックします

    BクリーンショットqBittorent。コンテキストメニューが開きます。強制チェックが選択されまたた
  8. はい、選択したトレントを再確認したいと確信しています。

    スクリーンショットqBittorent。再確認確認ウィンドウ。
  9. チェックが完了した後。 ディストリビューションを右クリックしてコンテキストメニューを呼び出し、[再開]アイテムをクリックします。

    スクリーンシットクットqBittorent。コンテキストメニューが開きます。選択を再開
  10. だから私たちは手元にとどまり、ディスクスペースを解放しました

    分布の欠落部分が表示されています。配布状況の配布
  11. ディストリビューションを右クリックしてコンテキストメニューを呼び出し、「移動」アイテムをクリックします(最初のアイテムでこれを行う必要がありますが、今日はそれについて考えました)

    BクリーンシットットqBittorent。コンテキストメニューが開きます。選択を移動
  12. ディレクトリ内のファイルが使用に適さないことが明確になるように、ディレクトリの名前を選択します。

    ディレクトリ選択選択ウィンドウのスクリリンショット。デイレクトリリが選択択されました!Sparse_files


SVGでの統計のカウント



画像







ファイルは100ブロックに分割されます。 チャートでは、完全なブロックのみが考慮されます。 グリッド内の各行は、1つの群れエミュレーションです。 マイルストーンのあるグリッドの下に、アクセシビリティグラフが一番下に表示されます。







  1. 青色のグラフの各ブロックの下の列は、完了したサイクルの数を示しています。
  2. 濃い青(実際には半透明の灰色)チャートでは、利用可能なデータの割合が左(0%)から右(100%)に表示され、この割合が上から下に利用可能なサイクル数が表示されます。


エミュレーションで遊んでみたい人のために: https : //ivan386.github.io/sparse_light/emulator.svg







キーボード制御:

P/



一時停止

+/=



-1つのソースを追加

-/_



-1つのソースを削除する







マウス制御:

グリッドをクリックすると、すべてのソースから消去される割合を選択できます。 右に行くほど消去されます。







グラフを解析する



  1. 5つのソースが異なる位置からファイルの81%を消去しました。 ただし、ほとんどのサイクルで64%が利用可能です。 ほとんどの場合、端のブロックにはアクセスできません。

    画像
  2. 5つのソースが異なる位置からファイルの49%を消去しました。 ファイルの88%はまだ使用可能です。

    ファイルの半分未満が解放されるため、スクリプトは消去する位置を選択します。 したがって、ファイルの中央では、ブロックはエッジよりもアクセスしにくくなります。

    画像
  3. 5つのソースが異なる位置からファイルの52%を消去しました。 ファイルの86%はまだ使用可能です。

    ファイルの半分以上を消去するために選択します。 この場合のスクリプトは、データの位置を選択し、このピースの前後で消去します。

    画像
  4. 5つのソースが異なる位置からファイルの40%を消去しました。 ファイルの100%のみが使用可能です。 ここでは、5つのソースを持つファイルの最大40%を消去すると、100%のファイルアクセシビリティが得られる可能性が高いことがわかります。

    画像


チャート2と3は互いに相殺します。







おわりに



ディスク領域を解放するこの方法は、大きなファイルを含む配布に適しています。 コンテンツが不要になったら、一部を消去して残りを配布できます。







ソース



  1. スパースファイル
  2. NTFSのスパースファイル
  3. FSCTL_SET_SPARSE制御コード
  4. FSCTL_SET_ZERO_DATA制御コード
  5. FILE_ZERO_DATA_INFORMATION構造
  6. Windowsバッチファイルで "are you sure"プロンプトを表示するにはどうすればよいですか?
  7. バッチスクリプトの呼び出しで読み取ることができる環境変数をvbsに設定する方法



All Articles