如何预测ISO 9660文件系统的大小?

时间:2009-01-22 05:20:15

标签: filesystems dvd-burning iso9660

我正在将数据归档到DVD,我想要将DVD打包完整。我知道DVD上我想要的所有文件的名称和大小,但我不知道元数据占用了多少空间。我想在每张DVD上获得尽可能多的文件,所以我使用了一个带有贪婪的bin-packing的Bubblesearch启发式算法。我尝试了10,000种替代方案并获得最佳选择。目前我知道所有文件的大小,因为我不知道文件如何存储在ISO 9660文件系统中,我为元数据添加了大量的slop。我想减少污泥。

我可以使用genisoimage -print-size,但它太慢了 - 假设40,000个文件占用500MB,则大约需要3秒。每张DVD需要8小时不在卡片中。我以前修改了genisoimage源代码,我真的不想尝试从源代码中挤出算法;我希望有人知道更好的估算方法,或者能指出一个有用的规范。


澄清问题和问题:

  • 我需要刻录分割在多张DVD上的档案,通常一次约五张。我试图解决的问题是决定将哪些文件放在每张DVD上,以便每张DVD(除了最后一张)尽可能充分。这个问题是NP难的。

  • 我正在使用标准的贪婪打包算法,您首先放置最大的文件,然后将其放入第一张有足够空间的DVD中。所以j_random_hacker,我肯定不是从随机开始。我从排序开始并使用Bubblesearch来扰乱文件的打包顺序。此程序将我的包装从估计容量的约80%提高到估计容量的99.5%以上。这个问题是关于更好地估算容量;目前我估计的容量低于实际容量。

  • 我编写了一个尝试10,000次扰动的程序,每个程序包含两个步骤:

    1. 选择一组文件
    2. 估算这些文件在DVD上的占用空间
    3. 第2步是我正在努力改进的步骤。正如Tyler D所暗示的那样,目前我正在“谨慎行事”。但我想做得更好。我不能使用genisomage -print-size,因为它太慢了。同样,我不能将文件tar到磁盘,因为它只是太慢,但tar文件与ISO 9660图像的大小不同。这是我需要预测的ISO 9660图像的大小。原则上这可以完全准确地完成,但我不知道该怎么做。这是个问题。


注意:这些文件位于具有3TB硬盘存储空间的计算机上。在所有情况下,文件的平均大小至少为10MB;有时候它会大得多。所以有可能genisomage毕竟会足够快,但我怀疑它 - 似乎是通过将ISO映像写入/ dev / null来工作,我无法想象它会足够快当图像大小接近4.7GB时。我现在无法访问该计算机,或者当我发布原始问题时。当我确实在晚上访问时,我会尝试获得更好的数字。但我不认为genisomage会是一个很好的解决方案 - 尽管它可能是学习文件系统模型的好方法 这告诉我它是如何工作的。知道块大小是2KB已经有用了。

知道同一目录中的文件被刻录到samae DVD也很有用,这简化了搜索。我希望直接访问这些文件,这会排除tar-before-burning。 (大多数文件都是音频或视频,这意味着尝试用gzip命中它们没有意义。)

5 个答案:

答案 0 :(得分:2)

我不确定你目前是怎么做的 - 根据我的谷歌搜索,“冒泡搜索”指的是一种选择某种意义上的物品排序 near 贪婪的方法订购,但在您的情况下,将文件添加到DVD的顺序不会改变空间要求,因此这种方法会浪费时间考虑多个不同的订单,这些订单相当于设置的文件。

换句话说,如果您正在执行以下操作来生成候选文件列表:

  1. 随机随机播放文件列表。
  2. 从列表顶部开始,贪婪地选择您估计适用于DVD的所有文件,直到不再有。
  3. 然后,您正在低效地搜索解决方案空间 - 对于任何 n 文件的最终候选集,您可能正在考虑所有 n !制作那套的方法。我的建议是:

    1. 按文件大小的递减顺序对所有文件进行排序。
    2. 将顶部(最大)文件标记为“包含”,并将其从列表中删除。 (它必须包含在某些DVD中,所以我们现在也可以将它包括在内。)
    3. 列表中最顶层的文件是否可以包含但(估计的)ISO文件系统大小超过DVD容量?如果是这样:
      • 概率 p (例如 p = 0.5),将文件标记为“包含”。
    4. 从列表中删除最顶层的文件。
    5. 如果列表现在为空,则您有一个候选文件列表。否则,转到3。
    6. 重复多次并选择最佳文件列表。

      Tyler D的建议也很好:如果你有~40000个文件总计~500Mb,那意味着平均文件大小为12.5Kb。 ISO 9660使用2Kb的块大小,这意味着这些文件平均浪费1Kb的磁盘空间,或大约8%的大小。因此,首先将它们与tar一起包装将节省大约8%的空间。

答案 1 :(得分:2)

感谢您的详细更新。我很满意您当前的装箱策略非常有效。

关于这个问题,“完全 ISO 9660文件系统打包了 n 文件总共 b 字节的开销是多少?”只有两个可能的答案:

  1. 有人已经编写了一个有效的测量工具。一个快速的谷歌搜索没有发现什么,但令人沮丧。 SO上的某个人可能会回复他们的自制工具的链接,但如果你几天没有得到更多回复,那么这可能也是如此。
  2. 您需要阅读readily available ISO 9660 specs并自行构建此类工具。
  3. 实际上,还有第三个答案:

    (3)您并不真正关心在每张DVD上使用每个最后一个字节。在这种情况下,抓住一小部分代表不同大小的文件(比如5),填充它们直到它们是2048字节的倍数,并将所有2 ^ 5个可能的子集放到genisoimage -print-size。然后在该数据集上拟合等式 nx + y = iso_size - total_input_size ,其中 n =给定运行中的文件数,以查找 x ,这是每个文件的开销字节数, y ,这是不变的开销量(不包含文件的ISO 9660文件系统的大小)。舍入 x y 并使用该公式估算给定文件集的ISO文件系统大小。为了安全起见,请确保使用出现在集合中任何位置的最长文件名作为测试文件名,并将每个文件名放在与集合中最深层次结构一样深的单独目录层次结构中。

答案 2 :(得分:1)

无法使用tar将文件存储在磁盘上? 目前还不清楚你是在写一个程序来做这个,还是只是做一些备份。

也许做一些实验并谨慎行事 - 磁盘上的一些可用空间不会受到伤害。

不知怎的,我想你已经考虑过这些了,或者我的回答是错过了这一点。

答案 3 :(得分:1)

我最近进行了一项实验,找到一个公式来对dvds进行类似的填充估算,并根据一些假设找到了一​​个简单的公式......从你原来的帖子中,这个公式对你来说可能是一个很小的数字,听起来像你有多个目录和更长的文件名。

假设:

  • 所有文件都是8.​​3个字符。
  • 所有文件都在根目录中。
  • 没有像Joliet这样的扩展名。

公式:

174 + floor(count / 42) + sum( ceil(file_size / 2048) )
  • count是文件数
  • file_size是每个文件的大小(以字节为单位)
  • 结果是2048个字节块。

示例脚本:

#!/usr/bin/perl -w
use strict;
use POSIX;

sub sum {
    my $out = 0;
    for(@_) {
        $out += $_;
    }
    return $out;
}

my @sizes = ( 2048 ) x 1000;
my $file_count = @sizes;

my $data_size = sum(map { ceil($_ / 2048) } @sizes);
my $dir_size = floor( $file_count / 42 ) + 1;
my $overhead = 173;

my $size = $overhead + $dir_size + $data_size;

$\ = "\n";
print $size;

我在最多150k文件的磁盘上验证了这一点,大小范围从200字节到1 MiB。

答案 4 :(得分:0)

好的想法,J。随机。当然我不需要每个最后一个字节,这主要是为了好玩(并在午餐时吹牛的权利)。我希望能够在CD-ROM上输入du并使其非常接近4700000000。

我查看了ECMA规范,但是像大多数规格一样,这是中等痛苦的,我对自己的能力没有信心。此外,它似乎不讨论Rock Ridge扩展,或者如果它,我错过了它。

我喜欢你的想法#3并认为我会更进一步:我将尝试构建一个相当丰富的模型,然后在许多文件集上使用genisoimage -print-size来估计参数该模型。然后我可以使用该模型进行估算。这是一个爱好项目所以需要一段时间,但我最终会解决它。我会在这里发一个答案,说明消耗了多少浪费!