Baixando um torrent de 16 GB através de um tablet com 4 GB de espaço livre

Baixando um torrent de 16 GB através de um tablet com 4 GB de espaço livre

Tarefa:

Existe um PC sem Internet, mas é possível transferir o arquivo via USB. Existe um tablet com Internet a partir do qual este arquivo pode ser transferido. Você pode baixar o torrent necessário em seu tablet, mas não há espaço livre suficiente. O arquivo no torrent é único e grande.

Caminho para a solução:

Iniciei o torrent para baixar. Quando o espaço livre estava quase acabando, pausei o download. Conectei o tablet ao PC e movi o arquivo do tablet para o PC. Fiz uma pausa e para minha surpresa o arquivo foi criado novamente e o torrent continuou baixando como se nada tivesse acontecido.

Devido ao fato do cliente torrent definir o sinalizador esparso para o arquivo no qual grava os dados recebidos, o sistema não tenta reservar 16 GB de uma vez e não ocorrerá erro ao tentar gravar em um arquivo além de 4 GB.

Depois de repetir o procedimento quatro vezes, recebi quatro arquivos em meu PC contendo diferentes partes do mesmo torrent. Agora só falta juntá-los. O procedimento é essencialmente simples. Você precisa substituir os zero bytes por outro valor se ele existir em uma determinada posição em um dos quatro arquivos.

Pareceu-me que um programa tão simples deveria estar na Internet. Ninguém nunca encontrou tal problema? Mas percebi que nem sei quais palavras-chave procurar. Portanto, criei rapidamente um script Lua para esta tarefa e agora o otimizei. Isto é o que quero compartilhar.

Baixando o torrent em partes

  1. comece a baixar o torrent no primeiro dispositivo
  2. espere até que a ROM seja preenchida
  3. pausar o download
  4. transfira o arquivo para o segundo dispositivo e adicione um número ao nome do arquivo
  5. voltamos ao primeiro ponto até que o arquivo seja baixado completamente

Mesclando peças em um arquivo

Após o recebimento da última parte, é necessário reuni-las em um arquivo inteiro.

A tarefa é simples:

  1. Lendo todas as partes de uma vez
  2. Se em alguma parte a posição não for um byte zero, então o escrevemos na saída, caso contrário, escrevemos zero

Função merge_part aceita uma matriz de threads streams_in dos quais lê uma parte do tamanho buffer_length e retorna o resultado da mesclagem de peças de diferentes threads.

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

Função string.gsub é adequado para a tarefa porque encontrará peças preenchidas com zeros e entregará o que lhe for dado.

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

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

string.gsub não transmite a posição em que a correspondência foi encontrada. Portanto, fazemos uma busca paralela pela posição zero_string usando a função string.find. Basta encontrar o primeiro byte zero.

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

--[[

Agora se em in_part há dados para out_part copie-os.

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

Cortar de in_part parte correspondente à sequência de zeros.

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

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

В part existem dados.

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

part acabou sendo menor que uma sequência de zeros. Vamos complementá-lo com eles.

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

Conclusão

Assim, conseguimos baixar e montar este arquivo em um PC. Após a fusão, retirei o arquivo torrent do tablet. Instalei um cliente de torrent no meu PC e verifiquei o arquivo com ele.

A última parte baixada no tablet pode ser deixada na distribuição, mas é necessário habilitar a nova verificação das partes anteriores e desmarcar o arquivo para que ele não seja baixado novamente.

Usava:

  1. Cliente de torrent flud em tablet.
  2. Cliente Torrent qBittorent no PC.
  3. Escrita Lua

Fonte: habr.com

Adicionar um comentário