ディストリビュヌションに戻るか、䞍可胜なこずをする方法

背景


少し前、぀たり6月5日にalan008ずいう名前のハヌバヌマンが質問をしたした 。 詳现を求めないように、ここに圌を連れおきたす。

助けが必芁です

数幎にわたり、さたざたなクラむアント䞻にuTorrentによっお、さたざたな䟿利なコンテンツの倚くのギガバむトがさたざたなトラッカヌ䞻にrutrackerを䜿甚からダりンロヌドされおきたした。 ダりンロヌドされたファむルは、その埌手動であるドラむブから別のドラむブに移動され、uTorrentはそれに応じおそれらを衚瀺したせん。 倚くの.torrentファむルはそれ自䜓では叀くなっおいたすたずえば、シリヌズの配垃は、.torrentファむルを眮き換えお新しいシリヌズを远加するこずにより実行されたした。

さお、質問自䜓コンピュヌタヌ䞊の.torrentファむルずコンピュヌタヌの異なる論理ドラむブに散圚するコンテンツずの間の察応を自動的に手動ではなく確立する方法はありたすか 目的䞍芁な無関係な.torrentファむルを削陀し、実際のファむルでは-配垃物にすべおを眮きたす。 誰がアむデアを持っおいたすか :)

必芁に応じお必芁な堎合、同じ論理ドラむブ䞊の1぀のディレクトリにすべおのデヌタファむルを再床配眮できたす。

議論は、これができるのであれば、ペンでしかできないこずに同意した。 この質問は私にずっおは面癜そうで、䌑暇から戻った埌、時間をかけお敎理したした。

.torrentファむル圢匏の解析に合蚈1週間を費やし、解析甚の䜜業ラむブラリを探しお、䞊蚘の質問で発生した問題を解決するプログラムの䜜成を開始したした。

始める前に、いく぀かの点に泚意する䟡倀がありたす。
  1. 倚くのこずが刀明したしたが、すべおではありたせんでした。
  2. .torrentファむル圢匏では、必芁な説明のみが提䟛されたす。
  3. 時々䜎品質のコヌドに敏感な人は私を蚱しおください-倚くの方がより良く、より最適に、゚ラヌなしで曞けるこずを知っおいたす。

技術的な詳现ず萜ずし穎-猫の䞋で、それから来たものに興味がある人のために。


この堎合、それを解決するための玠晎らしい方法がありたす-再びポンプでくみたす。 しかし、私たちは簡単な方法を探しおいたせん。そのようなオプションが提案されたした したがっお、困難なタスクを解決したす- ダりンロヌドしないでください 。

プログラムの䜜成を開始するずきは、たずその操䜜の少なくずも基本的なアルゎリズムに぀いお考える必芁がありたす。 この堎合、アルゎリズムは基本的に2぀のステップで構成されたす。

  1. すべおの.torrentファむルを芋぀けお読み取りたす。
  2. .torrentで説明されおいるものず䞀臎するファむルヒヌプを探し、.torrentのパスに察応するフォルダヌに移動したす。

私のアむデアを実装するために、私はCを䜿甚したしたが、ベンコヌド圢匏のファむルを読み蟌むためのラむブラリを備えた蚀語はこれに適しおおり、SHA-1ハッシュを読み蟌むこずが可胜です。

さお、タスクの解決策に進みたしょう。

トレントを探しお読む



デバむスの.torrent-filesを芋぀けた埌、このすべおの奇跡を解析するずいう問題に盎面したした。 このテヌマでむンタヌネットを粟査しお、このビゞネスのためのいく぀かの.NETラむブラリを発芋したした。 BencodeLibraryラむブラリで遞択を遞択したしたが、倚かれ少なかれ明確で、すぐに䜿甚できたすが、埌でニヌズに少し远加する必芁がありたしたが、それに぀いおは埌で詳しく説明したす。

.torrentを読むずいう最も単玔な瞬間から始めたしょう。

.torrentファむルの構造は非垞に単玔です。これは、 ベンコヌド圢匏の蟞曞です。 この蟞曞では、 情報キヌずのペア、぀たりファむル蚘述ブロックのみに関心がありたす。 これも蟞曞であり、ファむルの名前、サむズに関する情報が含たれおいたす。 さらに、倚くの人が知っおいるように、急流はファむルを完党にではなく、特定の長さの断片にハッシュしたす。これはこれらのファむルのサむズに䟝存したす。 この䜜品のサむズに関する情報も情報蟞曞に含たれおいたす。

読み取ったファむルからの情報を保存するには、次のTorrentクラスを䜿甚したす。
クラス急流
 public class Torrent { public Torrent(string name, List<LostFile> files, int pieceLength, char[] hash, string fileName) { Name = name; Files = files; PieceLength = pieceLength; Hash = hash; FileName= fileName; } public string Name; public int PieceLength; public char[] Hash; public List<LostFile> Files; public string FileName; ... } 

ここで、フィヌルドには次の情報が栌玍されたす。

* Name -トレント名䞀般的に蚀えば-フォルダヌ名たたはファむル名
* Files -今埌怜玢する必芁があるファむルのリスト
* PieceLengthこれらのピヌスのサむズ、考慮すべきハッシュ
* Hash -すべおのファむルのハッシュ文字列
* FileNameディスク䞊の.torrentファむルの名前

ハッシュラむンに泚目する䟡倀がありたす。 非垞に簡単に構成されおいたす。 すべおのファむルは次々ず事実䞊接着され、1぀のBIGOOOOOOOYの仮想ファむルを圢成したす。 この架空のファむルでは、 PieceLengthの長さの断片を取埗し、SHA1ハッシュを考慮し、ハッシュを行に入れ、次の断片を取埗し、ハッシュを考慮し、前の断片のハッシュで行の末尟に远加したす。 ぀たり、すべおのピヌスのハッシュの通垞の連結です。



泚意深い読者が気付くように、クラス内のファむルは単なるファむルではなく、 LostFile型の特定の構造によっおファむルが蚘述される特別なデヌタ型です。 ここにありたす
クラスLostFile
 public class LostFile { public LostFile(string name, long length, long beginFrom) { Name = name; Length = length; BeginFrom = beginFrom; } public string Name; public long Length; public long BeginFrom; . . . } 

ここではすべおが簡単です。ファむルの名前ずサむズです。 さらに、このクラスには、 BeginFrom別のフィヌルドが含たれおいたす。 その倧きな想像䞊のファむルでこのファむルの始たりを説明しおいたす。 ハッシュを蚈算するには、ファむルの正しい郚分を取埗する必芁がありたす-ファむルの長さが断片の長さの倍数になるこずは非垞にたれです。



必芁な情報を保存するための構造を準備したら、それらを埋めるこずができたす。

むンタヌネットにあるBencodeLibraryラむブラリを䜿甚しお、.torrentファむルを読み取り、そこから情報ブロックをルヌトしたす。

 List<LostFile> files = new List<LostFile>(); //  ,   BDict torrent = (BDict)BencodingUtils.DecodeFile(filename, Encoding.UTF8); BDict fileInfo = (BDict)torrent["info"]; 

次に、このブロックから、トレントの名前、ピヌスのサむズに関するデヌタを収集する必芁がありたす。

 string name = ((BString)fileInfo["name"]).Value; int pieceLength = (int)((BInt)fileInfo["piece length"]).Value; 

ハッシュの読み取りに問題がありたしたが、その解決策はあたり奜きではありたせんが、うたくいきたす。 実際、仕様によれば、.torrentファむルのすべおの行はUFT8にある必芁がありたす。 仕様に埓っお、UTF8文字列ずしおベンコヌド文字列の圢匏で蚘述されたハッシュを読み取るず、比范の問題が発生したす-同䞀の断片のハッシュは䞀臎したせん。 提案された゚ンコヌドコヌドペヌゞ437のトレントを読むず、パス内のロシア文字に問題がありたす。 異なる゚ンコヌディングで2回読むずいう、2日間の速床を萜ずすような状況から抜け出す方法を芋぀けたした。

 torrent = (BDict)BencodingUtils.DecodeFile(filename, Encoding.GetEncoding(437)); char[] pieces = ((BString)((BDict)torrent["info"])["pieces"]).Value.ToCharArray(); 

この時点で、゚ンコヌド情報を2番目のパラメヌタヌずしお `BencodingUtils.DecodeFile`メ゜ッドに枡したす。 これはたさに、ラむブラリにメ゜ッドを1぀远加しなければならなかった瞬間です-最初はcodepage-437がコヌドに瞫い付けられおいたした。

この郚分で最も興味深いポむントに到達したした-ファむル情報の読み取り。 トレントファむルには2぀のタむプがありたす。 これらのタむプは、それらに蚘述されおいるファむルの数が異なりたす。 .torrentで1぀のファむルのみを蚘述する堎合、その名前ずサむズが曞き蟌たれたす。

最初に、1぀のファむルの説明を䜿甚しお.torrentを分析したす。

 long Length = ((BInt)fileInfo["length"]).Value; files.Add(new LostFile(name, Length, 0)); // files -   

ここではすべおが単玔です-トレントの名前はファむル名ず同じです。 ディストリビュヌションに倚数のファむルがある堎合、それらを入れるフォルダヌの名前が名前フィヌルドに曞き蟌たれたす実際には、䜕でも構いたせんが、䜕らかの理由で、誰もがこれらのファむルが䜜成時に配眮されたフォルダヌの名前を曞き蟌みたす。 さらに、各ファむルに関する情報パスずサむズを含むファむルのリストが衚瀺されたす。 サむズが敎数の堎合、ファむルパスは文字列ディレクトリ名のリストであり、このファむルを介しお衚瀺されたす。

これは、䟋によっお最もよく説明されたす。 ファむルlevel_1\level_2_1\file_1.txtおよびlevel_1\level_2_2\file_2.txt堎合、それらを配垃する堎合、 名前フィヌルドには最䞊䜍フォルダヌの名前 "level_1" が含たれ、ファむルの1぀のパスリストは次のようになりたす {"level_2_1", "file_1.txt"}および{"level_2_2", "file_2.txt"}別の。

耇数のファむルを含む.torrentの堎合、各ファむルぞのパスを1行で収集する必芁がありたす。 さらに、各ファむルの先頭をそのBOLSHOOOOMに保存する必芁がありたす忘れないでください、本圓に。

 BList filesData = (BList)fileInfo["files"]; long begin = 0; foreach (BDict file in filesData) { BList filePaths = (BList)file["path"]; long length = ((BInt)file["length"]).Value; string fullPath = name; foreach (BString partOfPath in filePaths) { fullPath += @"\" + partOfPath.Value; } files.Add(new LostFile(fullPath, length, begin)); // files -   begin += length; } 


BOLSHOOOOOMファむル内のファむルの順序は任意であり、必ずしもアルファベット順たたはサむズではないこずに泚意するこずが非垞に重芁です。 ただし、 ファむルリスト内のファむルの順序はたったく同じになりたす。 これは、ハッシュの原理を理解するための鍵です。 たずえば、最初の図に瀺す状況では、ファむルのリストは次のようになりたす {"file_3","file_1", ..., "file_2"} 。 したがっお、あるファむルのハッシュを考慮するず、次に取埗する必芁があるファむルがわかりたす。

このすべおを読んでカりントしたら、 Torrentコピヌを䜜成しお返したしょう。

 new Torrent(name, files, pieceLength, pieces, filename); 

.torrentファむルのすべおの読み取り倀ず分析をたずめお収集するず、次のようになりたす。
ReadTorrent
 static Torrent ReadTorrent(string filename) { List<LostFile> files = new List<LostFile>(); BDict torrent = (BDict)BencodingUtils.DecodeFile(filename); BDict fileInfo = (BDict)torrent["info"]; string name = ((BString)fileInfo["name"]).Value; int pieceLength = (int)((BInt)fileInfo["piece length"]).Value; torrent = (BDict)BencodingUtils.DecodeFile(filename, Encoding.GetEncoding(437)); char[] pieces = ((BString)((BDict)torrent["info"])["pieces"]).Value.ToCharArray(); if (fileInfo.ContainsKey("files")) // Multifile torrent { BList filesData = (BList)fileInfo["files"]; long begin = 0; foreach (BDict file in filesData) { BList filePaths = (BList)file["path"]; long length = ((BInt)file["length"]).Value; string fullPath = name; foreach (BString partOfPath in filePaths) { fullPath += @"\" + partOfPath.Value; } files.Add(new LostFile(fullPath, length, begin)); begin += length; } } else // Singlefile torrent { long Length = ((BInt)fileInfo["length"]).Value; files.Add(new LostFile(name, Length, 1)); } return new Torrent(name, files, pieceLength, pieces, filename); } 

必芁なデヌタがすべお揃ったので、最も興味深いこず、぀たりファむルの怜玢の準備ができたした。

ファむルを探しおいたす



アルゎリズムの2番目のステップの実装に近づきたした。 これを行うには、次のフォヌムのFindFilesメ゜ッドを䜿甚したす。

 void FindFiles(Torrent torrent, List<FileInfo> files, string destinationPath) {} 

ここで、 filesは怜玢察象のファむルのリストfilesは、芋぀かったファむルが配眮される宛先フォルダヌぞのパスです。

.torrentの各ファむルに぀いお、ヒヌプからすべおのファむルを反埩凊理し、それらを比范したす。 ハッシュのチェックは非垞に高䟡なので、最初に巊偎のファむルを明瀺的にクリアする必芁がありたす。 さお、自分で刀断しおください。ディスコグラフィヌを.mp3にダりンロヌドしお移動しおも、明らかにファむル拡匵子は倉曎したせんでした。 名前は倉曎できたすが、拡匵子はほずんどありたせん。

 FileInfo fileOnDisk = files[j]; if (fileOnDisk.Extension != Path.GetExtension(fileInTorrent.Name)) continue; 

ファむルの長さも確認する䟡倀がありたすが、これはすでに疑わしいものであり、誀怜知を匕き起こす堎合がありたす。 拡匵子によっお明瀺的に残されたファむルをふるいにかけた埌にのみ、ハッシュのチェックを開始できたす。

 if (!torrent.CheckHash(i, fileOnDisk)) continue; 

怜蚌が完了し、ファむルが探しおいるものず䞀臎するこずを確認した埌、正しいパスで宛先フォルダヌに移動したす。 移動する前に、ディレクトリの存圚を自然に確認し、そのようなファむルがすでにあるかどうかも確認したす。 copyFileナヌザヌがフォヌムから枡した倉数、その目的は誰にでも明らかだず思いたす。

 FileInfo fileToMove = new FileInfo(destinationPath + @"\" + fileInTorrent.Name); if (!Directory.Exists(fileToMove.DirectoryName)) Directory.CreateDirectory(fileToMove.DirectoryName); if (!fileToMove.Exists) { // -  if (copyFile) File.Copy(fileOnDisk.FullName, fileToMove.FullName); else File.Move(fileOnDisk.FullName, fileToMove.FullName); //     files.Remove(fileOnDisk); //     torrent.Files.RemoveAt(i--); break; //      ,      torrent } 

䞊蚘のコヌドで説明する重芁な3぀のポむントがありたす。 最埌の2぀から始めたしょう-これらの行

 files.Remove(fileOnDisk); torrent.Files.RemoveAt(i--); 

゜ヌト枈みのファむルを考慮から陀倖するこずは非垞に論理的であるこずがわかりたした。これにより、怜玢の実行時間がわずかに短瞮されたす。 2行目には、構成.RemoveAt(i--);が含たれおい.RemoveAt(i--); 珟圚の芁玠はコレクションから削陀されるため、次の芁玠がルヌプを通過するのではなく、ルヌプの次の反埩で取埗されるように、ポむンタヌを戻す必芁がありたす。

最初の瞬間に぀いお。 リストにforeachが存圚するこずは知っおいたすが、それを䜿甚する堎合、このスピヌカヌを倉曎するこずはできたせん。぀たり、既に䞍芁な芁玠を削陀するこずはできたせん。 したがっお、䞊蚘のすべおを1぀の方法で収集するず、次のようになりたす。
ReadTorrent
 public static void FindFiles(Torrent torrent, List<FileInfo> files, string destinationPath, bool copyFile) { for (int i = 0; i < torrent.Files.Count; i++)// (LostFile fileInTorrent in torrent.Files) { LostFile fileInTorrent = torrent.Files[i]; for (int j = 0; j < files.Count; j++) { FileInfo fileOnDisk = files[j]; //       if (fileOnDisk.Extension != Path.GetExtension(fileInTorrent.Name)) continue; //   if (fileOnDisk.Length != fileInTorrent.Length) continue; //   if (!torrent.CheckHash(i, fileOnDisk)) continue; //   .     //   FileInfo fileToMove = new FileInfo(destinationPath + @"\" + fileInTorrent.Name); if (!Directory.Exists(fileToMove.DirectoryName)) Directory.CreateDirectory(fileToMove.DirectoryName); if (!fileToMove.Exists) { if (copyFile) File.Copy(fileOnDisk.FullName, fileToMove.FullName); else File.Move(fileOnDisk.FullName, fileToMove.FullName); //      files.Remove(fileOnDisk); //     torrent.Files.RemoveAt(i--); break; } } } } 

よくここに 最もおいしい。

ハッシュチェック



䞊蚘のコヌドからわかるように、ハッシュを確認するために、ディスク䞊のファむル名ずトレントファむルのリスト内のファむル番号を転送したす。 これは、ファむルのリストで怜玢を開始するのではなく、既知であるため、すぐに番号で怜玢するために必芁ですルヌプの別の「+1」。

 public class Torrent { public string Name; public int PieceLength; public char[] Hash; public List<LostFile> Files; public string FileName; public bool CheckHash(int index, FileInfo fileOnDisk) {} } 

それでは、ハッシュ怜蚌メ゜ッドの実装に取り​​掛かりたしょう。 この段階で、トレントファむルのリストの番号ずディスク䞊のファむルぞのパスがわかりたす。

 LostFile checkingFile = this.Files[index]; if (checkingFile.Length < this.PieceLength * 2 - 1) return false; 

原則ずしお、任意のファむルのハッシュを考慮するこずができたすが、タスクを少し簡単にしたしょう。 長さがPieceLength * 2 - 1以䞊のファむルのみを䜿甚したす。 このような制限により、怜蚌のために少なくずも1぀の郚分を分離できたす。これは完党にファむル内にありたす。 このアプロヌチには、いく぀かの重芁な利点がありたす。
  1. ディスク䞊の隣接ファむルを远加で怜玢する必芁はありたせん。
  2. ハッシュチャンクの長さが2〜4 MBを超えるこずはめったにありたせん。これにより、パフォヌマンスず時間の点で、ディスク䞊のファむルを探すよりもはるかに簡単にダりンロヌドできたす。

この段階で、私たちはやらなければならないこずの䞭で最も困難なこず-怜蚌のための適切なピヌスを芋぀けるこずになりたした。 プログラミングから少し離れお、数孊に目を向けお、補助的な問題を定匏化したしょう。

トレントクラむアントがファむルをハッシュするず、ハッシュが順番に考慮されたすが、1぀以䞊のファむルが存圚しないこずが起こりたす。 次に、トレントクラむアントは、次のピヌスを取埗し、次に䜿甚可胜なファむルのどこから開始するかを知る必芁がありたす。 これらの2桁を蚈算するには、次のコヌドを䜿甚したすfirstChunkNumber倉数には、このファむルに完党に含たれる最初のピヌスの番号ず、 bytesOverheadファむルの先頭からこのピヌスの先頭たでのバむト数が含たれたす。 この点をよりよく理解するには、コヌドの埌の説明図をご芧ください。

 long start = 0; long firstChunkNumber = 0; long bytesOveload = checkingFile.BeginFrom % this.PieceLength; if (bytesOveload == 0) //        { start = checkingFile.BeginFrom; firstChunkNumber = checkingFile.BeginFrom / this.PieceLength; } else { firstChunkNumber = checkingFile.BeginFrom / this.PieceLength + 1; start = firstChunkNumber * this.PieceLength - checkingFile.BeginFrom; } 




「その開始がファむルの開始ず䞀臎する堎合ず、ピヌスが内郚にある堎合ずではなぜピヌス番号が異なるのか」ずいう質問に察する答えは、独立しお提案されおいたす。

ピヌスの番号がわかったら、次の構成を䜿甚しおトレントからハッシュを取埗する必芁がありたす。

 char[] hashInTorrent = new char[20]; // 20 -   SHA1   Array.Copy(this.Hash, firstChunkNumber * 20, hashInTorrent, 0, 20); 

その埌、ファむルからピヌスを読み取り、そのハッシュを蚈算する必芁がありたす。

 char[] fileHash = new char[this.PieceLength]; using (BinaryReader fs = new BinaryReader(new FileStream(fileOnDisk.FullName, FileMode.Open))) { using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider()) { byte[] piece = new byte[this.PieceLength]; fs.BaseStream.Position = start; fs.Read(piece, 0, this.PieceLength); fileHash = Encoding.GetEncoding(437).GetString(sha1.ComputeHash(piece)).ToCharArray(); } } 

さお、最も重芁なこずはそれをチェックするこずです。 䜕らかの理由で、私にずっおは、 Equals()メ゜ッドが芋぀からなかったため、次の方法でチェックしたす。

 for (int i = 0; i < fileHash.Length; i++) { if (fileHash[i] != hashInTorrent[i]) return false; } 

興奮した脳の䜜成をたずめるず、次の内容のメ゜ッドが埗られたす。
チェックハッシュ
 public bool CheckHash(int index, FileInfo fileOnDisk) { LostFile checkingFile = this.Files[index]; if (checkingFile.Length < this.PieceLength * 2 - 1) return false; long start = 0; long firstChunkNumber = 0; long bytesOveload = checkingFile.BeginFrom % this.PieceLength; if (bytesOveload == 0) { start = checkingFile.BeginFrom; firstChunkNumber = checkingFile.BeginFrom / this.PieceLength; } else { firstChunkNumber = checkingFile.BeginFrom / this.PieceLength + 1; start = firstChunkNumber * this.PieceLength - checkingFile.BeginFrom; } char[] hashInTorrent = new char[20]; Array.Copy(this.Hash, firstChunkNumber * 20, hashInTorrent, 0, 20); char[] fileHash = new char[this.PieceLength]; using (BinaryReader fs = new BinaryReader(new FileStream(fileOnDisk.FullName, FileMode.Open))) { using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider()) { byte[] piece = new byte[this.PieceLength]; fs.BaseStream.Position = start; fs.Read(piece, 0, this.PieceLength); fileHash = Encoding.GetEncoding(437).GetString(sha1.ComputeHash(piece)).ToCharArray(); } } for (int i = 0; i < fileHash.Length; i++) if (fileHash[i] != hashInTorrent[i]) return false; return true; } 

この玠晎らしいメモで、方法ずアルゎリズムの物語は終わり、私たちはこの創造の実生掻における実珟の物語に移りたす。 この問題が解決するために私によっお解決されたのではなく、実珟するために解決されたこずは非垞に明らかです。 したがっお、私は、䞊に曞かれたものすべおを実装する私の創造物を公開裁刀所に持ち蟌みたす。

プログラム



プログラムは、Cで既に述べたように曞かれおいたす。 䜜業䞭はあたり気たぐれではなく、.NET 2.0のみが必芁です。 ただし、その䜿甚には1぀の制限がありたす。トレントファむルずコレクションを論理ドラむブのルヌトから削陀するこずをお勧めしたす。 この制限の理由は、ディレクトリをスキャンするずきに「SearchOption.AllDirectories」パラメヌタを䜿甚するためです。これは、ごみ箱や「システムボリュヌム情報」などの閉じたディレクトリを読み取ろうずするずクラッシュしたす知識のある人がこれを回避する方法を教えおくれたら、ずおも感謝しおいたす。 もちろん、宛先フォルダヌには特別な制限はありたせん。䞻なこずは、それが収たるこずであり、それに曞き蟌むこずができたす。そうしないずクラッシュしたすシミュレヌトしたせんでしたが、論理的に。

プロセスでは、次のファむルの凊理埌、結果が衚瀺されたす-ディスク䞊の.torrentファむルの名前ず凊理されたファむルの数。



スキャンを開始するには、3぀のディレクトリ.torrentファむル、䞊べ替え甚のファむル、および䞊べ替え甚のフォルダを遞択し、オプションで2぀のオプションを指定しおスキャンを開始する必芁がありたす。

パフォヌマンスに぀いお。 ただ䜎い10個の倧きなトレントファむルの凊理には玄5分かかりたした。

アプリケヌションは1぀のスレッドで動䜜するため、実行時にむンタヌフェむスがフリヌズしたすが、䜜業䞭です。 たた、ハッシュを怜蚌できないため、小さなファむル2メガバむト未満は移動されないこずをお知らせしたす。 誀firstChunkNumber 、番号firstChunkNumber䞋の1぀のピヌスのみfirstChunkNumberされるずいう事実が原因である可胜性が非垞に高いです。 これたでのずころ、すべおのピヌスをチェックするのは非垞に高䟡ですが、蚈画がありたす。

ディスクのルヌトで収集されたトレントを再垰的に怜玢しないでください。
コピヌには時間がかかるため、むンタヌフェむスがフリヌズする可胜性がありたす。心配しないでください。

この4funプログラムは曞かれおいるので、コヌドの品質は私が望んでいるものずは少し異なりたすが、私にずっおはうたくいきたす。 このプログラムはテストされおおらず、明らかな゚ラヌのみが修正されたため、隠れおいる可胜性がありたすが、隠れおいるバグがありたす。 このプログラムを䜿甚するず、あなたは自分の責任でそれを䜿甚したす。

゜ヌスはgithubで入手できたす 。 GPLv2で配垃。 実行可胜ファむルを含むアヌカむブがありたす。 䜜業にはBencode Libraryが必芁ですが、元のラむブラリは必芁ありたせんが、私が修正したした リポゞトリにあり、サブモゞュヌルで接続されおいたす 。

忍耐を瀺し、この蚘事を最埌たで読んでくれた皆さんに感謝したす。 あなたの質問を聞いお喜んで、アルゎリズム、特にコヌドを改善するためのあらゆる皮類の助けを歓迎したす。

゜ヌス BitTorrentSpecification

UPD1。 議論の結果に基づいお、配垃甚のファむルを匕っ匵っお既存のコレクションを壊さずに、むしろ正しいコレクション内のファむルぞの配垃甚の適切な堎所にハヌドリンクを䜜成する方が正しいこずが明らかになりたした䟋えば、映画やディスコグラフィヌ。 将来、プログラムはそのように機胜したす。

UPD2。 このナヌティリティを䜿甚した人が機胜やバグレポヌトに関しお他に垌望がある堎合は、問題トラッカヌのgithubに残しおください。

Source: https://habr.com/ru/post/J150608/


All Articles