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

我正在将数据存档到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次扰动的程序,每个程序包含两个步骤: 选择一组文件 估计这些文件在DVD上占用多少空间 第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
来点击它们没有意义。)     
已邀请:
感谢您的详细更新。我很满意您当前的装箱策略非常有效。 关于这个问题,“对于总共b字节的n个文件,ISO 9660文件系统打包了多少开销?”只有2个可能的答案: 有人已经编写了一个有效的测量工具。一个快速的谷歌搜索没有发现什么,但令人沮丧。 SO上的某个人可能会回复他们的自制工具的链接,但如果你几天没有得到更多的回复,那么这可能也是如此。 您需要阅读现成的ISO 9660规范并自己构建这样的工具。 实际上,还有第三个答案: (3)你并不真正关心每张DVD上的每一个字节。在这种情况下,抓住一小部分不同大小的代表(比如5),填充它们直到它们是2048字节的倍数,并将所有2 ^ 5个可能的子集通过
genisoimage -print-size
。然后在该数据集上拟合方程nx + y = iso_size - total_input_size,其中n =给定运行中的文件数,以找到x,即每个文件的开销字节数,以及y,即常量的开销(不包含文件的ISO 9660文件系统的大小)。舍入x和y并使用该公式来估计给定文件集的ISO文件系统大小。为安全起见,请确保使用集合中任何位置出现的最长文件名作为测试文件名,并将每个文件名放在与集合中最深层次结构一样深的单独目录层次结构中。     
我不确定你目前是怎么做的 - 根据我的谷歌搜索,“冒泡搜索”指的是一种选择在某种意义上接近贪婪订购的物品排序的方法,但在你的情况下,顺序是将文件添加到DVD不会改变空间要求,因此这种方法会浪费时间考虑多个不同的订单,这些订单相当于同一组文件。 换句话说,如果您正在执行以下操作来生成候选文件列表: 随机地随机播放文件列表。 从列表顶部开始,贪婪地选择您估计适用于DVD的所有文件,直到不再需要。 然后,您正在低效地搜索解决方案空间 - 对于n个文件的任何最终候选集,您可能正在考虑所有n!制作那套的方法。我的建议: 按文件大小的降序排序所有文件。 将顶部(最大)文件标记为“包含”,并将其从列表中删除。 (它必须包含在某些DVD上,所以我们现在也可以将它包括在内。) 是否可以包含列表中最顶层的文件,而(估计的)ISO文件系统大小超过DVD容量?如果是这样: 利用概率p(例如p = 0.5),将文件标记为“包含”。 从列表中删除最顶层的文件。 如果列表现在为空,则您有一个候选文件列表。否则,转到3。 重复此操作并选择最佳文件列表。 Tyler D的建议也很好:如果你有~40000个文件总计~500Mb,这意味着平均文件大小为12.5Kb。 ISO 9660使用2Kb的块大小,这意味着这些文件平均浪费1Kb的磁盘空间,或大约8%的大小。因此,首先将它们与tar一起包装将节省大约8%的空间。     
无法使用tar将文件存储在磁盘上? 目前还不清楚你是在写一个程序来做这个,还是简单地做一些备份。 也许做一些实验并谨慎行事 - 磁盘上的一些可用空间不会受到伤害。 不知怎的,我想你已经考虑过这些了,或者我的答案忽略了这一点。     
我最近做了一个实验来找到一个公式来对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。     
好的想法,J。随机。当然我不需要每个最后一个字节,这主要是为了好玩(并在午餐时吹牛的权利)。我希望能够在CD-ROM上键入
du
,并且非常接近4700000000。 我查看了ECMA规范,但是像大多数规格一样,它是中等痛苦的,我对自己的能力没有信心。此外它似乎不讨论Rock Ridge扩展,或者如果它,我错过了它。 我喜欢你的想法#3并认为我会更进一步:我将尝试构建一个相当丰富的模型,然后在许多文件集上使用
genisoimage -print-size
来估计模型的参数。然后我可以使用该模型进行估算。这是一个爱好项目,所以需要一段时间,但我最终会解决它。我会在这里发一个答案,说明消耗了多少浪费!     

要回复问题请先登录注册