Sťahovanie 16 GB torrentu cez tablet so 4 GB voľného miesta
cieľ:
K dispozícii je PC bez internetu, ale je možné preniesť súbor cez USB. Existuje tablet s internetom, z ktorého je možné tento súbor preniesť. Požadovaný torrent si môžete stiahnuť do svojho tabletu, ale nie je dostatok voľného miesta. Súbor v torrente je jeden a veľký.
Cesta k riešeniu:
Spustil som torrent na stiahnutie. Keď sa voľné miesto takmer minulo, sťahovanie som pozastavil. Pripojil som tablet k PC a presunul súbor z tabletu do PC. Pozastavil som sa a na moje prekvapenie sa súbor znova vytvoril a torrent pokračoval v sťahovaní, akoby sa nič nestalo.
Vzhľadom na to, že torrent klient nastavuje príznak sparse súboru, do ktorého zapisuje prijaté dáta, systém sa nepokúša rezervovať 16GB naraz a pri pokuse o zápis do súboru nad 4GB nedôjde k chybe.
Po štvornásobnom opakovaní postupu sa mi do počítača dostali štyri súbory obsahujúce rôzne časti toho istého torrentu. Teraz ich ostáva už len poskladať. Postup je v podstate jednoduchý. Musíte nahradiť nulové bajty inou hodnotou, ak existuje na danej pozícii v jednom zo štyroch súborov.
Zdalo sa mi, že taký jednoduchý program by mal byť na internete. Nestretol sa ešte nikto s takýmto problémom? Ale uvedomil som si, že ani neviem, aké kľúčové slová to mám hľadať. Preto som rýchlo vytvoril Lua skript pre túto úlohu a teraz som ho optimalizoval. O toto sa chcem podeliť.
Sťahovanie torrentu po častiach
začnite sťahovať torrent na prvom zariadení
počkajte, kým sa ROM naplní
pozastaviť sťahovanie
preneste súbor do druhého zariadenia a k názvu súboru pridajte číslo
vrátime sa k prvému bodu, kým sa súbor úplne nestiahne
Zlúčenie častí do jedného súboru
Po prijatí poslednej časti je potrebné ich zhromaždiť do jedného celého súboru.
Úloha je jednoduchá:
Čítanie všetkých častí naraz
Ak v niektorej časti pozícia nie je nulový bajt, tak ju zapíšeme na výstup, inak zapíšeme nulu
Funkcia merge_part prijíma pole vlákien streams_in z ktorých číta časť veľkosti buffer_length a vráti výsledok zlúčenia častí z rôznych vlákien.
function merge_part(streams_in, buffer_length)
local out_part
for _, stream in ipairs(streams_in) do
local in_part = stream:read(buffer_length)
if not out_part then
out_part = in_part -- просто копируем часть из первого файла
elseif in_part and #in_part > 0 then
if #out_part < #in_part then
out_part, in_part = in_part, out_part
end
if out_part ~= in_part -- данные различаются
and in_part:find("[^ ]") -- есть данные в in_part
and out_part:find(" ", 1, true) -- есть пустые места в out_part
then
local find_index = 1
--[[
Funkcia string.gsub je vhodný pre danú úlohu, pretože nájde figúrky plné nul a doručí to, čo je mu dané.
--]]
out_part = out_part:gsub(" +", function(zero_string)
if #in_part < find_index then
return -- не на что менять
end
--[[
string.gsub neuvádza polohu, na ktorej bola zhoda nájdená. Preto vykonávame paralelné vyhľadávanie pozície zero_string pomocou funkcie string.find. Stačí nájsť prvý nulový bajt.
Teraz ak v in_part existujú údaje pre out_part skopírujte ich.
--]]
if #in_part >= start_index then
local end_index = start_index + #zero_string - 1
--[[
Vystrihnúť z in_part časť zodpovedajúca postupnosti núl.
--]]
local part = in_part:sub(start_index, end_index)
if (part:byte(1) ~= 0) or part:find("[^ ]") then
--[[
В part existujú údaje.
--]]
if #part == #zero_string then
return part
else
--[[
part sa ukázalo byť menej ako postupnosť núl. Doplňme to nimi.
--]]
return part..zero_string:sub(1, end_index - #in_part)
end
end
end
end)
end
end
end
return out_part
end
Záver
Takto sme si mohli stiahnuť a zostaviť tento súbor na PC. Po zlúčení som z tabletu vytiahol torrent súbor. Nainštaloval som si do počítača torrent klienta a skontroloval som s ním súbor.
Posledná stiahnutá časť na tablete môže zostať v distribúcii, ale predtým je potrebné povoliť opätovnú kontrolu častí a zrušiť začiarknutie súboru, aby sa znova nestiahol.