文件分配表读取
我正在开发一个自定义 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 数组并重写整个 chainmap。
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());
}
我一直在研究缓存系统,但我想有更多关于如何使其变得更好的想法。
I am working on a custom FAT file system explorer and things have been going quite well. However, I want to know if there is a better way to efficiently read/write to the chainmap. For large devices, this can be incredible resource intensive and it can be very, very slow. Especially when allocation space.
Here is how I read it:
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();
}
The chain can sometimes be hundreds of megabytes.
And this is how I write it. When allocation and modifications to the chainMap uint array have been done, it will basically loop through that uint array and rewrite the entire chainmap.
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());
}
I have been working on a cache system, but I want to have some more ideas on how to make this better.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看来你可以以某种方式将其分割。不是读取/写入整个内容,而是根据使用情况进行“页面输入/输出”块。想想虚拟内存系统可以从中获得灵感。
It seems like you could segment it somehow. Rather than read/write the whole thing, 'page in/out' chunks based on usage. Think about virtual memory systems for inspiration there.
我自己对二进制序列化进行了大量的研究和测试,让我印象深刻的一件事是,你可以使用当今的硬盘快速读取相当大的块,并且大部分时间实际上花在将字节转换为整数、字符串等上。
因此,您可以做的一件事是重新架构以利用所有核心,首先读取尽可能大的数据块,然后使用 PLINQ 或 Parallel.net 进行实际的反序列化。您甚至可能想进一步了解生产者/消费者模式。您只会看到大量条目或大块或数据的收益,但通常不值得并行化。
另外,您有一个查找语句,这些语句总是很昂贵,请尝试使用内存映射文件或立即读取大块(如果可能且适用)。
I've done a lot of research and testing on binary serialization myself and one thing that struck me was that you could read pretty big blocks quickly with todays harddrives and that the lion part of time was actually spent converting bytes into integers, strings etc.
So, one thing you could do is rearchitecture to make use of all your cores, first read as big block of data as possibly and then use PLINQ or Parallel.net to do the actual deserialization. You might even want to go even further into a producer/consumer pattern. You'll only see gains for large number of entries or large blocks or data though otherwise it's usually not worth parallelizing.
Also, you have a seek statement, those are always expensive, try using a memorymappedfile or reading a big block right away if possible and applicable.