难度问题:海量的小文件存储(300分)

  • 主题发起人 主题发起人 Adnil
  • 开始时间 开始时间
1. xiaopei算是个高手了, 方法很不错;
2. 还是固定大小的数据块好很多, 3K,4K又何妨(硬盘大的很啊), 成本不考虑, 处理简单很多;
3. 编程操作时还有些优化细节的, 例如删除,添加数据等处理, 不过都很简单;
 
我觉得比较好的方法是创建一个索引文件和一个内容文件。如调用例子
var index[0..1000000] of Pointer; //首先定义一个以最大文件名数据大小的数据索引文件。这个索引以文件名数值当数组上标和下标存取偏移,这样做索引文件是大了一点,但是可以省略搜索偏移的时间。
index[文件名ID] := 文件名ID内容的偏移地址。
在以后的读取当中,就可以打开索引文件和内容文件。首先在索引文件中以:
文件名ID偏移 := index[文件名ID]; //这样直接获取内容文件的偏移而不用搜索的办法取得索引偏移,速度是很可观的。


有个新问题,文件数量虽然在100万之内,但是文件名ID可能超过100万的,只是一个cardinal范围内的数字。
 
1. 如果固定不超过100万, 没有必要分两个文件; // 就像很多字库文件, 索引头就放在文件头部; 当然, 你为了编程方便, 单独分开也可以的;
2. 其实整数检索几乎不耗时间的, 所以说: 也无所谓排序检索; // 你可以参考以下测试代码, 这是我以前因为要处理类似问题所做的测试:
const maxcount = 1000000; // 你可以改到 1000万都很快的
var a : array[1..maxcount] of integer;

procedure TForm1.Button1Click(Sender: TObject);
var t1,t2 : TDatetime;
i : integer;
x : integer;
begin
for i := 1 to maxcount do
begin
a := 123;
end;
x := 321;
t1 := time;
for I := 1 to maxcount do
begin
if a = x then
begin
x := a;
end;
end;
t2 := time;
x := millisecondsbetween(t2, t1);
showmessage(inttostr(x));
end;
 
文件名ID不固定,这是个问题,不过如新世纪所说,索引搜索100万个在速度上不会很慢。几个毫秒就可以完成。所以,建立一个索引,然后搜索就可以了,而且如果可以,你还可以将这些索引排一下序,然后用二分叉算法检索索引就更快了。
 
小文件的文件名,有重复没?
我以前做过类型的东西,按理来说很简单,就一个索引和一个内容文件,索引文件保存了内容信息,索引文件就几个字段,加载到内存,数量不大,for循环一下就找到。
一个索引,一个内容文件,先加载索引到内存,查找时在索引查找,找到后,到内容文件,一次定位,一次IO读取,好像是最优了吧???
如果你要对性能很挑的话,就完善一下索引检索问题,比如用hash来检索,这样,速度应该不成问题。
 
>>我前面提到过,这个数字没有规律的

mod 16相当于 楼上提到的hash了
反正你一个ID文件要占一簇 16个文件也占一簇
 
不如用一个大文件,分为几K的固定部份,每次读固定部分,比生成文件快。
 
后退
顶部