Filesystems 如何用很少的空闲磁盘空间连接两个巨大的文件?

Filesystems 如何用很少的空闲磁盘空间连接两个巨大的文件?,filesystems,concatenation,large-files,Filesystems,Concatenation,Large Files,假设您有两个巨大的文件(几GB)要连接在一起,但是您只有很少的空闲磁盘空间(比如说几百MB)。也就是说,给定file1和file2,您希望得到一个文件,它是将file1和file2逐字节连接在一起的结果,并删除原始文件 你不能做明显的catfile2>>file1;rm file2,因为在这两个操作之间,磁盘空间会用完 欢迎使用免费或非免费工具在任何和所有平台上提供解决方案;这是我前几天下载Linux ISO时想到的一个假设问题,下载中途由于无线故障而中断。由于这些限制,我希望您需要篡改文件系统

假设您有两个巨大的文件(几GB)要连接在一起,但是您只有很少的空闲磁盘空间(比如说几百MB)。也就是说,给定
file1
file2
,您希望得到一个文件,它是将
file1
file2
逐字节连接在一起的结果,并删除原始文件

你不能做明显的
catfile2>>file1;rm file2
,因为在这两个操作之间,磁盘空间会用完


欢迎使用免费或非免费工具在任何和所有平台上提供解决方案;这是我前几天下载Linux ISO时想到的一个假设问题,下载中途由于无线故障而中断。

由于这些限制,我希望您需要篡改文件系统;直接编辑文件大小和分配块


换言之,忘记乱洗任何文件内容块,只需编辑有关这些文件的信息。

我认为困难在于确定如何从原始文件中恢复空间

我认为以下方法可能有效:

  • 分配一个稀疏的 组合尺寸
  • 将100Mb从第二个文件的结尾复制到新文件的结尾
  • 截断第二个文件末尾的100Mb
  • 循环2和3,直到完成第二个文件(将2.修改到目标文件中的正确位置)
  • 执行2、3和4操作,但使用第一个文件
  • 这一切都依赖于稀疏文件支持,文件截断可以立即释放空间

    如果您确实想这样做,那么您应该研究
    dd
    命令。哪一个可以执行复制步骤

    在另一个答案中,有人给出了一个简洁的解决方案,该解决方案不需要稀疏文件,但可以复制file2两次:

  • 将100Mb块从文件2的末尾复制到新文件3,以相反的顺序结束。正在截断文件2
  • 将100Mb的块从文件3的末尾复制到文件1中,并以块的原始顺序结束,位于文件1的末尾。正在截断文件3

  • 冒着听上去轻率的风险,您是否考虑过只获得更大磁盘的选择?这可能会更快…

    两个想法:

    如果您有足够的物理RAM,您实际上可以将第二个文件完全读取到内存中,删除它,然后以追加模式将其写入第一个文件。当然,如果在删除后但在完成写入之前失去电源,则第二个文件的一部分将永久丢失


    暂时减少操作系统功能使用的磁盘空间(例如虚拟内存、“回收站”或类似功能)。可能只在Windows上使用。

    我怀疑这是对这个问题的直接回答。你可以认为这是解决问题的另一种方式。

    我认为可以将第二个文件作为第一个文件的第2部分。通常在zip应用程序中,我们会看到一个巨大的文件被分成多个部分。如果打开第一部分,应用程序会自动考虑其他部分的进一步处理。


    我们可以在这里模拟同样的事情。正如@edg所指出的,修补文件系统将是一种方法。

    花在找出涉及磁盘扇区洗牌和文件链操作的巧妙解决方案上的时间:2-4小时

    获取/编写软件进行就地复制和截断所花费的时间:2-20小时

    乘以每小时50美元的中间值程序员费率:400-1200美元

    1TB USB驱动器的成本:100-200美元


    理解“机会成本”一词的能力:无价的,效率不高,但我认为这是可以做到的


    以附加模式打开第一个文件,并将块从第二个文件复制到该文件,直到磁盘几乎满为止。对于第二个文件的其余部分,通过随机访问I/O将块从停止点复制回文件的开头。在复制最后一个块后截断文件。重复直到完成。

    好的,为了理论上的娱乐,并且只有在你承诺不浪费时间实际做的情况下:

    • 文件以片段形式存储在磁盘上
    • 这些碎片以链的形式连接在一起
    因此,您可以通过以下方式连接文件:

    • 将第一个文件的最后一段链接到最后一个文件的第一段
    • 更改第一个文件的目录项以更改最后一个文件和文件大小
    • 删除最后一个文件的目录项
    • 清理第一个文件的文件结束标记(如果有)
    • 注意,如果第一个文件的最后一个部分只被部分填充,则必须复制数据“up”最后文件的段以避免文件中间有垃圾[谢谢@楔!] /LI>。
    这将是最有效的:最少的修改,最少的复制,不需要多余的磁盘空间


    现在去买一个usb驱动器;-)

    显然,经济上的答案是购买更多存储空间,假设这是一个可能的答案。不过,它可能不是嵌入式系统,无法增加存储空间,甚至无法访问设备本身,比如说,飞行中的太空探测器

    如果您有一个稀疏文件系统,那么前面给出的基于稀疏文件系统的答案是好的(除了出错时它的破坏性!)。但如果你没有呢

    从文件2复制块的末尾开始,到目标文件的开头,边复制边反转。在每个块之后,将源文件截断为未复制的长度。对文件#1重复上述步骤

    此时,目标文件包含所有向后的数据,源文件消失

    从tart和目标文件的末尾读取一个块,反转它们并将它们写入另一个文件所在的位置。向内翻转积木

    完成后,目标文件是
    head file2 --bytes=1024 >> file1 && tail --bytes=+1024 file2 >file2 
    
    gzip file1
    
    gzip file2
    
    zcat file1 file2 | gzip > file3
    
    rm file1
    
    rm file2
    
    gunzip file3