Stahování 16GB torrentu přes tablet se 4GB volného místa

Stahování 16GB torrentu přes tablet se 4GB volného místa

Úkol:

K dispozici je PC bez internetu, ale je možné přenést soubor přes USB. Existuje tablet s internetem, ze kterého lze tento soubor přenést. Požadovaný torrent si můžete stáhnout do svého tabletu, ale není dostatek volného místa. Soubor v torrentu je jeden a velký.

Cesta k řešení:

Spustil jsem torrent ke stažení. Když bylo volné místo téměř pryč, pozastavil jsem stahování. Připojil jsem tablet k PC a přesunul soubor z tabletu do PC. Odmlčel jsem se a k mému překvapení se soubor znovu vytvořil a torrent pokračoval ve stahování, jako by se nic nestalo.

Vzhledem k tomu, že torrent klient nastaví příznak sparse souboru, do kterého zapisuje přijatá data, nesnaží se systém rezervovat 16GB najednou a při pokusu o zápis do souboru nad 4GB nedojde k chybě.

Po zopakování postupu čtyřikrát jsem na svůj počítač obdržel čtyři soubory obsahující různé části stejného torrentu. Teď už zbývá jen je poskládat. Postup je v podstatě jednoduchý. Musíte nahradit nulové bajty jinou hodnotou, pokud existuje na dané pozici v jednom ze čtyř souborů.

Zdálo se mi, že takový jednoduchý program by měl být na internetu. Nesetkal se ještě nikdo s takovým problémem? Ale uvědomil jsem si, že ani nevím, jaká klíčová slova to mám hledat. Proto jsem rychle vytvořil Lua skript pro tento úkol a nyní jsem jej optimalizoval. To je to, co chci sdílet.

Stahování torrentu po částech

  1. začněte stahovat torrent na prvním zařízení
  2. počkejte, až se ROM zaplní
  3. pozastavit stahování
  4. přeneste soubor do druhého zařízení a přidejte k názvu souboru číslo
  5. vrátíme se k prvnímu bodu, dokud se soubor zcela nestáhne

Sloučení částí do jednoho souboru

Po obdržení poslední části je nutné je shromáždit do jednoho celého souboru.

Úkol je jednoduchý:

  1. Čtení všech dílů najednou
  2. Pokud v některé části pozice není nulový bajt, pak ji zapíšeme na výstup, jinak zapíšeme nulu

Funkce merge_part přijímá pole vláken streams_in z nichž čte část velikosti buffer_length a vrátí výsledek sloučení částí z různých vláken.

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
--[[

Funkce string.gsub je pro daný úkol vhodný, protože najde dílky plné nul a dodá, co je mu dáno.

--]]
                out_part = out_part:gsub(" +", function(zero_string)

                    if #in_part < find_index then
                        return -- не на что менять
                    end
--[[

string.gsub nesděluje polohu, na které byla nalezena shoda. Provádíme proto paralelní hledání pozice zero_string pomocí funkce string.find. Stačí najít první nulový bajt.

--]]
                    local start_index = out_part:find(" ", find_index, true)
                    find_index = start_index + #zero_string

--[[

Nyní, pokud v in_part existují data pro out_part zkopírujte je.

--]]
                    if #in_part >= start_index then
                        local end_index = start_index + #zero_string - 1
--[[

Vyjmout z in_part část odpovídající posloupnosti nul.

--]]
                        local part = in_part:sub(start_index, end_index)

                        if (part:byte(1) ~= 0) or part:find("[^ ]") then
--[[

В part existují data.

--]]
                            if #part == #zero_string then
                                return part
                            else
--[[

part se ukázalo být menší než posloupnost nul. Pojďme to jimi doplnit.

--]]
                                return part..zero_string:sub(1, end_index - #in_part)
                            end
                        end
                    end
                end)
            end
        end
    end
    return out_part
end

Závěr

Tento soubor jsme tedy mohli stáhnout a sestavit na PC. Po sloučení jsem z tabletu vytáhl torrent soubor. Nainstaloval jsem si na PC torrent klienta a zkontroloval jsem s ním soubor.

Poslední stažený díl na tabletu lze ponechat v distribuci, ale je potřeba před tím povolit opětovnou kontrolu dílů a zrušit zaškrtnutí souboru, aby se znovu nestahoval.

Použitý:

  1. Flud torrent klient na tabletu.
  2. Torrentový klient qBittorent na PC.
  3. Skript Lua

Zdroj: www.habr.com

Přidat komentář