我有一个大小为2GB的文件,其中有学生记录。我需要根据每条记录中的某些属性找到学生,并创建一个包含结果的新文件。过滤学生的顺序应与原始文件中的顺序相同。使用Java IO API和线程执行此操作的最快方法是什么,而没有内存问题? JVM的maxheap大小设置为512MB。java中的文件处理
回答
- 2GB的文件是巨大的,你应该去一个数据库。
- 如果你真的想用Java I/O API,然后尝试了这一点:Handling large data files efficiently with Java这:Tuning Java I/O Performance
什么样的文件?基于文本的,如CSV?
最简单的方法是做类似grep的事情:逐行读取文件,解析行,检查过滤条件,如果匹配,输出结果行,然后转到下一行,直到文件已经完成了。这非常有效,因为您只有当前行(或缓冲区稍大)加载的同时。你的过程需要通读整个文件一次。
我不认为多线程会有很大的帮助。这会让事情变得更加复杂,并且由于无论如何这个过程似乎都是I/O约束,试图用多个线程读取同一个文件可能不会提高吞吐量。
如果你发现你需要经常这样做,每次浏览文件太慢,你需要建立某种索引。最简单的方法是先将文件导入数据库(可以是SQLite或HSQL等嵌入式数据库)。
哦,男孩,我打字完全一样的答案。事实上,所有这些都归结为只是一行一行地完成这项工作,而不是将整个事情存储在Java的内存中。 – BalusC 2010-08-20 01:34:17
我不会过度复杂,直到你发现无聊简单的方式不适合你的需要。从本质上讲,你只需要:
- 打开的输入流为2GB的文件,记住缓冲液(如用的BufferedInputStream包装)
- 打开的输出流过滤的文件,你要创建
- 读第一条记录从输入流中,查看任何属性来决定是否“需要”它;如果这样做,将其写入到输出文件
- 重复的剩余记录
我与极为有限的硬件测试系统之一,围绕一个FileInputStream的BufferedInputStream开箱即在25秒内,即阅读约500 MB大概在2分钟内处理你的2GB文件,并且默认的缓冲区大小基本上和它一样好(参见我所做的BufferedInputStream timings了解更多细节)。我想用最先进的硬件设备很可能时间会减半。
无论您需要花费很多精力来减少2/3分钟,或者只是在等待它运行的时间里等待一小段时间,您需要根据您的要求做出决定。我认为数据库选项不会给你多少钱,除非你需要在同一组数据上做很多不同的处理运行(还有其他解决方案不会自动表示数据库)。
+1,尤指因为“在你等待的时候过一小会儿” – 2010-08-20 04:16:42
我认为你应该使用memory mapped files.This将帮助你映射较大的文件到一个 较小的内存。这将像虚拟内存一样行事,就性能而言,映射文件比流写/读。
- 1. 文件处理Java
- 2. 使用处理库 - 在处理草图中的Java文件中?
- 3. 使用java中的文件处理
- 4. 如何处理Java中的文件集
- 5. 在java中的文件处理
- 6. java中的文件处理程序
- 7. 处理XML文件(JAVA)
- 8. 用Java处理ARJ文件
- 9. Java文件处理DisplayOnConsole
- 10. Java文件处理类
- 11. flush()java文件处理
- 12. Java中的事件处理
- 13. 在java中处理/读取.BAI2文件
- 14. 在Java中处理Excel文件
- 15. Java中的事件处理与C#中的事件处理
- 16. Java硬件中断处理
- 17. 文本文件处理 - 使用java
- 18. 文件处理的核心java
- 19. Java的并行文件处理
- 20. 处理从批处理文件运行Java的错误
- 21. 会java能够处理5000或更多文件的文件处理程序?
- 22. C中的文件处理
- 23. ABAP中的文件处理
- 24. COBOL中的文件处理
- 25. 处理php中的文件
- 26. JavaScript中的文件处理
- 27. c中的文件处理?
- 28. Erlang中的文件处理
- 29. 处理PSUnit中的文件
- 30. ReactJS中的文件处理
考虑将信息存储在数据库而不是2GB文件中。为学生做。 – polygenelubricants 2010-08-20 01:14:39
数据库不适合我。我会用纯文本文件获取数据,我必须处理它。 – 2010-08-20 01:19:17
无法将X磅的任何东西放入X/N包中,其中N> 1。您将永远不会将该文件的全部内容一次性压缩到内存中。 – duffymo 2010-08-20 01:24:49