通过具有 16GB 可用空间的平板电脑下载 4GB 的 torrent

通过具有 16GB 可用空间的平板电脑下载 4GB 的 torrent

问题:

有一台没有互联网的 PC,但可以通过 USB 传输文件。 有一台带有互联网的平板电脑,可以从中传输该文件。 您可以在平板电脑上下载所需的 torrent,但可用空间不足。 torrent 中的文件很大。

解决方案路径:

我开始下载种子。 当可用空间快用完时,我暂停了下载。 我将平板电脑连接到电脑,并将文件从平板电脑移动到电脑。 我停了下来,令我惊讶的是,文件又被创建了,并且 torrent 继续下载,就好像什么也没发生一样。

由于 torrent 客户端会在写入接收到的数据的文件中设置稀疏标志,因此系统不会尝试立即保留 16GB,并且在尝试写入超过 4GB 的文件时也不会发生错误。

重复该过程四次后,我在电脑上收到了四个文件,其中包含同一 torrent 的不同部分。 现在剩下的就是将它们放在一起。 该过程本质上很简单。 如果零字节存在于四个文件之一的给定位置,则需要将其替换为另一个值。

在我看来,这么简单的程序应该在互联网上。 难道没有人遇到过这样的问题吗? 但我发现我什至不知道用什么关键词来搜索它。 因此,我很快为这个任务创建了一个Lua脚本,现在我已经对其进行了优化。 这就是我想分享的。

分部分下载 torrent

  1. 开始在第一台设备上下载 torrent
  2. 等待ROM填满
  3. 暂停下载
  4. 将文件传输到第二台设备并在文件名中添加数字
  5. 我们返回第一点,直到文件完全下载

将各部分合并到一个文件中

收到最后一部分后,有必要将它们收集成一个完整的文件。

任务很简单:

  1. 一次性阅读所有部分
  2. 如果在某些部分该位置不是零字节,那么我们将其写入输出,否则我们写入零

功能 merge_part 接受线程数组 streams_in 其中读取 size 的一部分 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

结论

因此,我们能够在 PC 上下载并组装该文件。 合并后,我从平板电脑中取出种子文件。 我在我的电脑上安装了一个 torrent 客户端并用它检查了文件。

平板电脑上最后下载的部分可以保留在发行版中,但您需要在此之前启用对部分的重新检查,并取消选中该文件,以便它不会再次下载。

用过的:

  1. 平板电脑上的 Flud 种子客户端。
  2. PC 上的 Torrent 客户端 qBittorent。
  3. Lua脚本

来源: habr.com

添加评论