请教一下 Java 怎样写文件比较快

2017-07-14 19:12:39 +08:00
 dltsgl
一个 30 万条的大 list,逐条写到 txt 文件里,一条数据对应一行,用什么方法比较好?
现在用 PrintWriter 的 println 一行一行写,写一行要 10ms 左右,30 万行要 1 个小时左右,太慢了。
请教一下,应该怎样写比较快?
3550 次点击
所在节点    问与答
18 条回复
anyele
2017-07-14 19:17:51 +08:00
1 小时? 我试过 Excel to txt,一行一行写,5 万行的 Excel 只需要 4-5 秒
tanranran
2017-07-14 19:20:28 +08:00
list 转 string,然后用回车分割.然后一次性写到 txt 文件里.
ihuotui
2017-07-14 19:30:35 +08:00
nio
af463419014
2017-07-14 19:47:49 +08:00
nio+1
hcymk2
2017-07-14 19:59:29 +08:00
java youclass > res.txt
看下要花多长时间。
Accldent
2017-07-14 20:39:05 +08:00
先用 profiler 分析下大部分时间花在了哪儿再决定怎么优化,但是这种场景下用 NIO 得不到质的提升,只是从数据流变成数据块
hand515
2017-07-14 21:35:12 +08:00
看看磁盘的 IO 性能先
hyperdak
2017-07-14 21:57:06 +08:00
List<String> list = Lists.newArrayList();
FileUtils.writeLines(new File("e:\\abcdddd.txt"), "utf-8", list);

啷个阔能一小时嘛?
tomoya92
2017-07-14 22:20:34 +08:00
@hyperdak #8 FileUtils 是哪个包下的?
FreeFd
2017-07-14 22:32:06 +08:00
其实多线程写也可以呀,类似于多线程下载的技术
sagaxu
2017-07-14 23:17:15 +08:00
@FreeFd 多线程写可能会更慢
iEverX
2017-07-15 00:29:42 +08:00
只是第一行 10ms 吧,之后是顺序写,不可能一直 10ms
autulin
2017-07-15 02:26:16 +08:00
nio+内存映射
FreeFd
2017-07-15 02:58:14 +08:00
@sagaxu 如果瓶颈不是在磁盘 io 上,多线程更快些的。
DCjanus
2017-07-15 03:58:18 +08:00
持续写入,性能瓶颈主要在磁盘 IO。
猜测其中可优化点:
1. 使用 buffer 减少磁盘 IO 次数
2. 一次性创建所需大小的文件后再写入,在大多数文件系统上可以获得更好的效率

详细解释:
1. 磁盘每次写入,不管是写入 1 个字节还是 1K 字节,只要在一定范围内,时间相差不多,所以尽量攒够一波再写入
2. 每次都是追加文件尾,文件系统一开始并不知道你的文件大小,一开始先创建一个恰当大小的文件,文件系统更容易做出优化,不同的文件系统实现不同,此处略去。

相关参考:
1. 创建特定大小文件: http://jk-t.iteye.com/blog/1930414
2. 使用 BufferedWriter 写文件
Valyrian
2017-07-15 04:11:11 +08:00
明显是没 buffer 吧。。
hyperdak
2017-07-15 10:49:02 +08:00
@liygheart commons io
ihuotui
2017-07-15 18:33:23 +08:00
加上 4k 才刷盘,这样比较好,或者更大块,硬盘都是大块速度快,小文件慢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/375405

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX