2010-07-21 49 views
1

我正在开发一个自定义的FAT文件系统浏览器,事情进展得很顺利。但是,我想知道是否有更好的方法来高效地读写链表。对于大型设备,这可能是非常非常非常慢的资源密集型。特别是在分配空间时。文件分配表读取

这是我如何读它:

public void ReadChainMap() 
    { 
     chainMap = new uint[clusterCount]; 
     fx.Io.SeekTo(chainMapOffset); 
     EndianIo io = new EndianIo(fx.Io.In.ReadBytes((int)chainMapSize), EndianType.BigEndian); 
     io.Open(); 

     for (int x = 0; x < clusterCount; x++) 
      chainMap[x] = (chainMapEntrySize == 2) ? 
       io.In.ReadUInt16() : io.In.ReadUInt32(); 


     io.Close(); 
    } 

链有时可数百兆。

这就是我写它的方式。当对chainMap uint数组进行分配和修改时,它将基本上遍历该uint数组并重写整个链表。

public void WriteChainMap() 
    { 
     EndianIo io = new EndianIo(new byte[chainMapSize], 
      EndianType.BigEndian); 
     io.Open(); io.SeekTo(0); 

     for (int x = 0; x < clusterCount; x++) 
      if (chainMapEntrySize == 2) 
       io.Out.Write((ushort)chainMap[x]); 
      else 
       io.Out.Write(chainMap[x]); 

     fx.Io.SeekTo(chainMapOffset); 
     fx.Io.Out.Write(io.ToArray()); 
    } 

我一直在研究一个缓存系统,但我想对如何让这个更好一些有更多的想法。

回答

0

看来你可以以某种方式对它进行细分。而不是读取/写入整个事物,基于使用情况的“页面进/出”块。在那里考虑虚拟内存系统的灵感。

+0

嗯,事情是,分配时,你需要准备好它(在内存中是最简单的),并循环直到找到一个空闲的簇。你会这样做一个文件需要多少个群集。现在,如果我循环访问设备上的链表并读取整数值,那么将比在内存中读取它慢得多。 – Eaton 2010-07-21 17:52:25

0

我已经做了很多关于二进制序列化的研究和测试,有一件让我感到震惊的事情是,你可以用今天的硬盘快速读取很大的块,并且狮子部分时间实际上花费了将字节转换为整数,字符串等。

所以,你可以做的一件事是利用你的所有内核进行重构,首先作为可能的大块数据读取,然后使用PLINQ或Parallel.net来完成实际的反序列化。你甚至可能想进一步进入生产者/消费者模式。您只会看到大量条目或大块或数据的收益,否则通常不值得并行化。

此外,你有一个寻求声明,这些都是昂贵的,尝试使用memorymappedfile或马上阅读一个大块,如果可能和适用。

+0

感谢您的回复,认为这已经死了,哈哈。我确实想出了一个解决方案。我遍历分配表并仅记录空闲簇,然后将它们保存到文件中。然后在我需要写入新数据时打开该文件,并准备好下一个空闲群集。唯一的缺点是,它可能需要一段时间才能缓存非常大的驱动器。 – Eaton 2010-11-18 04:31:40