Pobieranie torrenta 16 GB za pomocą tabletu z 4 GB wolnego miejsca

Pobieranie torrenta 16 GB za pomocą tabletu z 4 GB wolnego miejsca

Zadanie:

Jest komputer bez Internetu, ale istnieje możliwość przesłania pliku przez USB. Istnieje tablet z internetem, z którego można przenieść ten plik. Możesz pobrać wymagany torrent na swój tablet, ale nie ma wystarczającej ilości wolnego miejsca. Plik w torrentie jest jeden i duży.

Droga do rozwiązania:

Uruchomiłem torrent do pobrania. Kiedy wolne miejsce prawie się skończyło, wstrzymałem pobieranie. Podłączyłem tablet do komputera i przeniosłem plik z tabletu na komputer. Zatrzymałem się i ku mojemu zdziwieniu plik został utworzony ponownie, a torrent kontynuował pobieranie, jakby nic się nie stało.

Ze względu na to, że klient torrentowy ustawia flagę sparse na plik, w którym zapisuje otrzymane dane, system nie podejmuje próby zarezerwowania 16 GB od razu i nie wystąpi błąd przy próbie zapisu do pliku powyżej 4 GB.

Po czterokrotnym powtórzeniu procedury otrzymałem na komputerze cztery pliki zawierające różne części tego samego torrenta. Teraz pozostało tylko je połączyć. Procedura jest zasadniczo prosta. Należy zastąpić bajty zerowe inną wartością, jeśli istnieje ona na danej pozycji w jednym z czterech plików.

Wydawało mi się, że taki prosty program powinien znaleźć się w Internecie. Czy nikt nigdy nie spotkał się z takim problemem? Ale zdałem sobie sprawę, że nawet nie wiem, jakie słowa kluczowe go szukać. Dlatego na szybko stworzyłem skrypt Lua do tego zadania i teraz go zoptymalizowałem. Właśnie tym chcę się podzielić.

Pobieranie torrenta w częściach

  1. rozpocznij pobieranie torrenta na pierwszym urządzeniu
  2. poczekaj, aż ROM się zapełni
  3. wstrzymaj pobieranie
  4. prześlij plik na drugie urządzenie i dodaj cyfrę do nazwy pliku
  5. wracamy do pierwszego punktu, aż plik zostanie pobrany całkowicie

Łączenie części w jeden plik

Po otrzymaniu ostatniej części należy zebrać je w jeden cały plik.

Zadanie jest proste:

  1. Czytanie wszystkich części na raz
  2. Jeśli w jakiejś części pozycja nie jest bajtem zerowym, to zapisujemy ją na wyjście, w przeciwnym razie zapisujemy zero

Funkcja merge_part akceptuje tablicę wątków streams_in z czego odczytuje część rozmiaru buffer_length i zwraca wynik łączenia części z różnych wątków.

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

Funkcja string.gsub nadaje się do tego zadania, ponieważ znajdzie kawałki wypełnione zerami i dostarczy to, co mu zostanie powierzone.

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

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

string.gsub nie informuje o pozycji, w której znaleziono dopasowanie. Dlatego prowadzimy równoległe poszukiwanie stanowiska zero_string za pomocą funkcji string.find. Wystarczy znaleźć pierwszy bajt zerowy.

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

--[[

Teraz, jeśli w in_part są dane dla out_part skopiuj je.

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

Wytnij z in_part część odpowiadająca ciągu zer.

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

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

В part są dane.

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

part okazała się mniejsza niż ciąg zer. Uzupełnijmy go nimi.

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

wniosek

W ten sposób mogliśmy pobrać i złożyć ten plik na komputerze. Po fuzji wyciągnąłem plik torrent z tabletu. Zainstalowałem klienta torrent na moim komputerze i sprawdziłem za jego pomocą plik.

Ostatnią pobraną część na tablet można pozostawić w dystrybucji, ale przed tym należy włączyć ponowne sprawdzanie części i odznaczyć plik, aby nie pobierał się ponownie.

Używany:

  1. Klient torrent Flud na tablecie.
  2. Klient torrent qBittorent na PC.
  3. Skrypt Lua

Źródło: www.habr.com

Dodaj komentarz