【发布时间】:2020-10-21 16:40:52
【问题描述】:
我有很多小文件。为了节省文件句柄和提高 IO 效率,这些文件被打包成一个大文件。但是,出于某种原因,这些小文件应该能够在运行时更新。所以需要不同线程同时更新和读取一个大文件的不同部分。
由于内存限制,mmap 不是一个好的选择。我必须自己实现它。但我担心在 iOS/Android 上同时读取和写入单个文件的不同部分是否安全。如何确保正在写入的块不会被其他线程读取。
我应该通过线程锁来实现整个功能还是已经有一些成熟的技术来做同样的工作?
顺便说一句,我在我的项目中使用 C++。但 Java 和 Obj-C 也是一种选择。
用户案例示例:
我的项目是一款 RPG 游戏。当人们看到一个未存储在原始包中的物品时,游戏会从服务器加载它并立即自动将其保存到磁盘中。
一个项目对应一个文件。每个文件差不多 300KB~1.5MB。服务器上有 3000~5000 个项目。在最坏的情况下,人们会在本地保存数千个文件。
好消息是我的用户可以按需加载项目以节省存储空间。并且在更新时,只会重新下载更改的项目。但是数千个文件将导致耗尽 FD 或其他资源的高风险。
这就是为什么我想将这些小文件打包成一个大包文件。但我仍然想保留更新/添加单个文件的能力。
【问题讨论】:
-
如果您打算使用这种方法,是的,C 中的锁仍然是一个东西。但是您甚至没有提及您正在使用的语言,我将假设
lseek到使文件处理程序跳转。您是否考虑过使用数据库来组织数据?在衡量它有多慢并知道它是否真的会影响您的性能之前,您是否尝试对其进行优化? mmap内存限制不是4GB吗,在这种情况下你真的打算在磁盘上有这么大的文件吗?为什么不使用 C api,在 ios 和 android 中都可用? -
@Fabio 感谢您的回复。我没有考虑使用数据库来管理我的数据。我的数据由 3000~5000 个小文件组成,平均大小为 500KB。我没有使用数据库处理二进制文件的经验。它适合我的情况吗?
-
@Fabio 对于 mmap,我的项目很耗内存。此功能只有 10~20M 的内存预算。我认为 mmap 会占用与磁盘上文件大小相同大小的内存。我打算制作 3~4 个 500MB 的文件来处理这个小文件。在最坏的情况下,它将占用 2GB 内存。所以,基本上,如果我使用 C API 并保持所有线程不读取/写入文件的同一块,我的项目会正常工作吗?
-
你是如何包装它们的?带拉链?
-
这不是文件支持的 mmap 的工作方式,它是虚拟内存,因此并没有像您想象的那样真正使用 RAM。现在坏消息是,iOS 不会让你映射超过 700 MB stackoverflow.com/questions/13425558/why-does-mmap-fail-on-ios。现在,在为您的问题构建解决方案时,请编辑您的问题,使用您期望的写入/读取频率是多少,以及是否有用户交互,例如点击按钮并期望特定的二进制文件(又名 blob)立即在屏幕上加载某些内容.有很多选择,用户交互可能会推动最佳解决方案。
标签: android ios file io operating-system