Изтегляне на 16GB торент през таблет с 4GB свободно пространство

Изтегляне на 16GB торент през таблет с 4GB свободно пространство

Цел:

Има компютър без интернет, но има възможност за прехвърляне на файла през USB. Има таблет с интернет, от който може да се прехвърли този файл. Можете да изтеглите желания торент на таблета, но няма достатъчно свободно място. Файлът в торента е един и голям.

Път на решение:

Пуснах торента за изтегляне. Когато свободното място почти свърши, поставих на пауза изтеглянето. Свързах таблета с компютъра и преместих файла от таблета на компютъра. Натиснах паузата и за моя изненада файлът беше създаден отново и торентът продължи да се люлее все едно нищо не се е случило.

Поради факта, че торент клиентът задава sparse флага на файла, в който записва получените данни, системата не се опитва да резервира 16GB веднага и няма да има грешка при опит за запис във файл над 4GB.

След като повторих процедурата четири пъти, получих четири файла на компютъра, в които има различни части от един и същ торент. Сега остава да ги сглобим. Процедурата по същество е проста. Необходимо е да замените нула байта с друга стойност, ако е на дадената позиция в един от четирите файла.

Струваше ми се, че такава проста програма трябва да бъде в Интернет. Наистина ли никой не се е сблъсквал с такава задача? Но разбрах, че дори не знам какви ключови думи да търся. Затова бързо добавих Lua скрипт за тази задача и сега го оптимизирах. Искам да ги споделя.

Изтегляне на торент част по част

  1. започнете да изтегляте торента на първото устройство
  2. изчакайте, докато ROM се напълни
  3. пауза на изтеглянето
  4. прехвърлете файла на второто устройство и добавете номер към името на файла
  5. връщаме се към първата точка, докато файлът бъде изтеглен напълно

Обединете части в един файл

След получаване на последната част е необходимо да ги съберете в един цял файл.

Задачата е проста:

  1. Четене на всички части едновременно
  2. Ако в някаква част позицията не е нулев байт, тогава я записваме на изхода, в противен случай записваме нула

Функция merge_part взема масив от нишки streams_in от които се чете размерът на частта buffer_length и връща резултата от сливането на части от различни нишки.

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

Функция string.gsub подходящ за задачата, тъй като ще намира фигури, пълни с нули, и ще поставя това, което му е подадено.

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

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

string.gsub не преминава позицията, на която е намерено съвпадението. Затова правим паралелно търсене на позиция zero_string използване на функцията string.find. Достатъчно е да намерите първия нулев байт.

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

--[[

Сега, ако в in_part има данни за out_part ние ги копираме.

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

Изрязани от in_part част от съответната последователност от нули.

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

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

В part има данни.

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

part се оказа по-малко от последователност от нули. Ние го допълваме с тях.

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

Заключение

По този начин беше възможно да изтеглите и сглобите този файл на компютър. След сливането изтеглих торент файла от таблета. Инсталирах торент клиент на моя компютър и проверих файла с него.

Последната изтеглена част на таблета може да бъде оставена в дистрибуцията, но трябва да включите повторната проверка на частите преди това и да премахнете отметката от файла, за да не се изтегля отново.

Използван:

  1. Flud торент клиент на таблет.
  2. Торент клиент qBittorent на компютър.
  3. lua скрипт

Източник: www.habr.com

Добавяне на нов коментар