如果我有一个大文件,我可以使用ln
它来制作它的“副本”,而不会占用额外的磁盘空间。但如果我不想要怎么办精确的文件的副本?有没有一种方法可以创建经过一些修改的文件的新版本,而无需复制整个文件并使用两倍的磁盘空间?
我的动机是编辑从 torrent 下载的 mp3 文件上的 id3 标签。我不想直接编辑下载的文件,因为这会弄乱播种,但我也不想复制文件并使用两倍的磁盘空间来编辑一些 id3 标签的标头。
答案1
如果您使用的程序中没有内置功能,覆盖新信息以某种方式通过基本文件,您必须在文件系统级别上解决这个问题,对使用该文件的应用程序透明。由于您的空间要求,修订控制系统是不够的,尽管它为您提供了多个版本。
您可以研究的一件事是将文件存储在 Btrfs 文件系统上,并将原始文件放在一个“原始”快照中,并将更新版本放在基于此快照的视图中。这对于 ID3v1 标签(因为它们是文件的末尾)以及具有 ID3v2 标签的文件来说应该很有效,只要它们有足够的保留空间用于更改并且不需要重写 MP3 文件。因此,只有文件更改的实际块才会占用额外的磁盘空间。
如果您在原始文件中添加其他文件,则必须明确说明cp --reflink src dst
稍后添加的所有文件。然后,您的下载内容将在派生视图上与原始版本、您的 id3 编辑器(例如 picard)和音乐播放器一起使用。该视图中未更改(或尚未更改)的文件看起来与原始文件完全相同。
示例(从 Btrfs 卷 on/data0
和test.mp3
文件 in开始/tmp
):
/data0$ btrfs subvolume create /data0/mp3org
Create subvolume '/data0/mp3org'
/data0$ cp /tmp/test.mp3 mp3org/
/data0$ btrfs subvolume snapshot /data0/mp3org/ /data0/id3update
Create a snapshot of '/data0/mp3org/' in '/data0/id3update'
该文件现在在两个目录 (和)test.mp3
中都可用:mp3org
id3update
/data0$ ls -l /data0/mp3org
total 7600
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:21 test.mp3
/data0$ ls -l /data0/id3update/
total 7600
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:21 test.mp3
更改快照中的一项:
/data0$ id3v2 -c "This is a change" id3update/test.mp3
/data0$ ls -l /data0/mp3org
total 7600
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:21 test.mp3
/data0$ ls -l /data0/id3update/
total 7608
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:24 test.mp3
文件大小没有改变,但第二个文件的内容改变了。这是因为注释确实适合原始文件中 id3v2 的保留空间。
/data0$ grep -F "is a change" mp3org/* id3update/*
Binary file id3update/test.mp3 matches
复制原始子卷中的另一个文件,它不会显示在id3update
:
/data0$ cp /tmp/test.mp3 mp3org/abc.mp3
/data0$ ls -l mp3org/ id3update/
id3update/:
total 7600
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:24 test.mp3
mp3org/:
total 15200
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:28 abc.mp3
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:21 test.mp3
制作显式的引用链接副本:
/data0$ cp --reflink mp3org/abc.mp3 id3update/
/data0$ ls -l mp3org/ id3update/
id3update/:
total 15200
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:29 abc.mp3
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:24 test.mp3
mp3org/:
total 15200
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:28 abc.mp3
-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:21 test.mp3
并更改新文件:
/data0$ id3v2 -c "another file change" id3update/abc.mp3
/data0$ grep -F change mp3org/* id3update/*
Binary file id3update/abc.mp3 matches
Binary file id3update/test.mp3 matches
如果mp3org
自动填充,您可以id3update
通过定期运行脚本来保持最新状态,该脚本cp --reflink src dst
在目标尚不存在时执行此操作。
¹最常出现在文件的开头
答案2
使用版本控制系统(例如 git),您可以“签入”或“提交”任意数量的文件版本。 Git 可能是最容易掌握的版本控制系统之一,因为它不需要使用单独的服务器;所有的工作都可以在您自己的本地计算机上完成,并且网络上有大量的教程信息。还有各种可用的图形前端。 Git 将在内部将不同的文件版本存储为原始文件和版本之间差异的压缩版本。作为提交过程的一部分,您提供一条消息,简要描述已提交文件的状态,然后您可以浏览可用版本并“签出”您当前想要使用的版本。
答案3
要找到差异,有命令diff
- 逐行比较文件。您可以存储差异,diff-file
并随时可以通过将patch
差异文件应用到原始文件来应用它。但无论如何,您应该首先创建第二个文件来进行更改(您可以在收到差异文件后将其删除)。
如果diff
即使使用参数也无法使用二进制文件--text
,您可以自由使用bsdiff
或,可能,rdiff
(谢谢安科供评论)。