我找不到问题的好标题,这就是我想要做的事情:
最好的方法是什么?
更新
答案 0 :(得分:3)
如果您想避免使用数据库,可以将它们存储为磁盘上的文件(以简化操作)。但是,在单个目录中维护大量文件时,需要注意文件系统注意事项。
许多常见的文件系统在某种顺序列表中维护每个目录的文件(例如,简单地一个接一个地存储文件指针或inode,或者在链接列表中。)这使得打开位于底部的文件这个清单真的很慢。
一个好的解决方案是将目录限制为少量节点(比如n = 1000),并在目录下创建一个文件树。
所以不要将文件存储为:
/ dir / file1 / dir / file2 / dir / file3 ... / dir / fileN
将它们存储为:
/ dir / r1 / s2 / file1 / dir / r1 / s2 / file2 ... / dir / rM / sN / fileP
通过这种方式拆分文件,可以显着提高大多数文件系统的访问时间。
(请注意,有一些新的文件系统代表树中的节点或其他形式的索引。这种技术也适用于那些。)
其他考虑因素是调整文件系统(块大小,分区等)和缓冲区缓存,以便获得良好的数据局部性。根据您的操作系统和文件系统,有很多方法可以执行此操作 - 您可能需要查找它们。
或者,如果这不能削减它,您可以使用某种嵌入式数据库,如SQLlite或Firebird。
HTH。
答案 1 :(得分:2)
我很想在C ++中使用数据库sqlite或coucheDB 这些都可以在.Net中工作,但我不知道是否有更好的.Net特定替代方案。
即使在可以处理目录中200,000个文件的文件系统上,也可以打开目录
编辑 - 数据库可能会更快!
文件系统不是为大量小对象设计的,数据库是。
它将实现你从未想过的各种聪明的缓存/事务策略。
有照片网站通过数据库选择文件系统。但他们主要是在相当大的blob上进行读取,他们有很多管理员专门为这个特定的应用程序调整他们的服务器。
答案 2 :(得分:2)
我建议创建一个具有单线程队列的类,用于将图像(gzip)转储到文件末尾,然后将文件offsets / meta-info保存到像sqlite这样的小型数据库中。这允许您从多个线程快速,紧密地存储所有文件,并有效地读取它们,而无需处理任何文件系统怪癖(除了max filesize之外 - 可以通过添加一些额外的元数据来处理)。
File:
file.1.gzipack
Table:
compressed_files {
id,
storage_file_id,
storage_offset,
storage_compressed_length,
mime_type,
original_file_name
}
答案 3 :(得分:1)
您可以查看mongoDb,它支持商店文件。
答案 4 :(得分:0)
确定的唯一方法是了解有关您的使用方案的更多信息。
例如,以后使用这些文件是否需要一次包含100个文件的群集?也许如果确实如此,将它们结合起来是有意义的。
在任何情况下,我都会尝试制作一个简单的解决方案,并且只有在您稍后发现存在性能问题时才进行更改。
这就是我要做的事情:
答案 5 :(得分:0)
我实际上不使用.NET,所以我不确定那里有什么容易,但总的来说我会提供两条建议。
如果你需要写很多并且很少阅读(例如日志文件),你应该创建一个.zip文件等(选择一个不会太慢降低性能的压缩级别;在1-9级别中) ,5左右通常适合我)。这给您带来了几个好处:您不会如此努力地访问文件系统,减少存储空间,并且您可以自然地将文件分组为100或1000或其他任何块。
如果你需要写很多和阅读很多,你可以定义自己的平面文件格式(除非你有权访问实用程序来读写.tar文件等,或作弊并将二进制数据放入8位灰度TIFF中。定义每个标头的记录 - 可能每个包含文件偏移量的1024个字节,文件名和您需要存储的任何其他内容 - 然后以块的形式写入数据。当您需要读取块时,首先读取标题(可能是100k),然后跳转到您需要的偏移量并读取您需要的量。固定大小标头的优点是你可以在开始时向它们写入空数据,然后只是将新内容添加到文件的末尾然后返回并覆盖相应的记录。
最后,你可能会看到像HDF5这样的东西;我不知道.NET对它的支持是什么,但它是存储通用数据的好方法。
答案 6 :(得分:0)
您可以考虑使用Microsoft的缓存应用程序块。您可以将其配置为使用IsolatedStorage作为后备存储,因此缓存中的项目将序列化为磁盘。性能可能是一个问题 - 我认为开箱即用它会阻止写入,因此您可能需要调整它以执行异步写入。
答案 7 :(得分:0)
在您的情况下memchached可能会遇到一些性能问题。