依次读取大量的小文件

依次读取大量的小文件,第1张

概述依次读取大量的小文件

我有这个问题:我有一个大小约为2000个字节的小文件(它们都是完全相同的大小)的集合,约有100.000个em,大约等于200兆字节的空间。 我需要能够实时地在这些文件中select一个范围。 说文件1000到1100(总共100个文件),读取它们并通过networking快速地发送它们。

好的是,文件总是按顺序读取的,也就是说,从这个文件和一百个文件开始,这个文件总是会变成一个范围,而不是“这里是这个文件,那边是那个文件等等”。

文件也可以在运行时添加到这个集合中,所以它不是一个固定数量的文件。

目前我提出的scheme是这样的:没有文件大于2000字节,所以,而不是有多个文件分配在磁盘上,我将有一个大文件包含所有其他文件,甚至2048字节间隔每个2048块的2个第一个字节是包含在接下来的2046个字节中的文件的实际字节大小(文件的大小在1800到1950个字节左右),然后在这个文件中search,而不是为每个文件打开一个新的文件句柄我需要阅读的文件。

一些大胆和一些简单的话在同一个语句

什么编程实践影响窗口句柄的数量?

监视文件/目录访问在C#

如果在.NET中valIDation文件的签名是否存储在系统的目录存储中?

固定的应用程序有错误的标题

所以当我需要在位置X处获取文件时,我只需执行X * 2048,读取前两个字节,然后从(X * 2048)+2中读取包含在前两个字节中的字节。 这个大的200mb文件将被追加,所以即使序列化的input线程/进程(尚未决定)追加更多的数据,也是安全的。

这必须在windows上可行,C是一个选项,但我更喜欢C#。

C#:如何判断EXE是否有图标?

特定networking接口IPv4可用性 – 无连接,本地,Internet

windowslogin的“使用条件”对话框

填充windows XP安全事件日志

windows服务自动启动和停止,exception处理问题

我认为你的想法可能是你能用体面的工作做的最好的。

或者,您可以购买固态硬盘,而不关心文件大小。

或者,如果不依靠保持RAM使用率低(也是最快的选择),则可以将整个数据预加载到内存中。

或者你可以使用数据库,但是这里的开销会很大。

你有什么反对在数据库中存储这些文件?

一个简单的RDBMS将大大加速搜索和排序一堆fo 2k文件

这听起来像是一个合理的选择。

当读取范围内的数据时,我很想尝试“数据块”的开始,并一次性读取整个内存(即所有文件的2048字节缓冲区)。 这将使文件IO降到最低。

一旦获得了存储器中的所有数据,就可以对大小进行解码,并只发送实际数据的位。

将所有内容加载到内存中可能是一个好主意,但这完全取决于它被修改的频率以及被查询的频率。

除了“这是一个合理的事情”之外还有更多的问题吗?

你确定你永远不会想要从1200到1400删除文件吗? 当你完成转移后会发生什么? 数据是否存档或将不断增长?

我真的不明白为什么将所有的数据附加到单个文件会提高性能。 相反,它可能会给你带来更多的问题。 那么,你为什么要把它们结合起来?

其他要考虑的事情是,如果大量文件从磁盘上的坏扇区中间受到损坏,会发生什么情况? 看起来你失去了一切。 保持他们分开应该增加他们的生存能力。

你当然可以使用大文件而不需要将整个内容加载到内存中,但是这并不容易,你最终必须下降到一些低级别的代码才能做到这一点。 不要束缚自己。 另外,如果该文件需要一些手工编辑呢? 大多数程序会迫使你加载和锁定整个事情。

而且,拥有一个大文件意味着你不能有多个进程读/写数据。 这限制了可扩展性。

如果您知道需要从#1000到1100的文件,则可以使用内置(c#)代码来获取满足该条件的文件集合。

您可以简单地连接一个大文件“dbase”中的所有文件,而不需要任何页眉或页脚。

在另一个文件的“索引”中,可以将所有小文件的位置保存在“dbase”中。 这个索引文件非常小,可以完全缓存在内存中。

该方案允许您快速读取所需文件,并在收藏结束时添加新文件。

你的计划听起来可行。 看起来像一个文件流可以执行查找和读取,你需要。 你是否遇到了具体的实现问题,或者你正在寻找一个更好的方法来做到这一点?

是否有一个更好的方法可能取决于你可以读取文件的速度,以及你在网络上传输文件的速度。 假设你可以读取大量单个文件,也许你可以设置一个有界的缓冲区,在这里你可以读取多少个文件到一个队列中。 另一个线程将从队列中读取并在网络上发送它们

我会用一种方法修改你的方案:不用读取前两个字节,然后使用这些来确定下一个读取的大小,我只是立即读取2KiB,然后使用前两个字节来确定你传输了多少字节。

通过仅使用一个磁盘读取,您可能会节省更多时间,而不是将最后约150个字节从磁盘传输到内存中。

另一种可能性是将文件的数据打包在一起,并维护一个单独的索引来告诉你每个文件的起始位置。 对于你的情况,这有一个好处,就是不用从磁盘上做很多小的(2K)读 *** 作,你可以把任意数字组合成一个大的读。 每读取一次达到64-128K左右,通常会节省相当多的时间。

你可以坚持你的一个大文件的解决方案,但使用内存映射来访问它(见这里例如)。 这可能会更高性能,因为您也避免了分页,并且虚拟内存管理针对传输4096字节的块进行了优化。 Afaik没有对内存映射的直接支持,但是这里是一些如何包装C#的WIN32 API调用的例子。

在这里也可以看到关于SO的相关问题。

有趣的是,这个问题让我想起了这个老的SO问题:

这对高级Java开发人员角色来说是一个过度的问题吗?

总结

以上是内存溢出为你收集整理的依次读取大量的小文件全部内容,希望文章能够帮你解决依次读取大量的小文件所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1292369.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存