1
timonwong 2012-11-05 15:46:07 +08:00
mmap?
|
2
zenomac 2012-11-05 15:49:37 +08:00
file对象没有删除一行的方法。
语言上好像只能重写入。(才疏学浅啊) 不如加一些标记作为作废一行的指示符。 |
3
phuslu 2012-11-05 16:01:19 +08:00
试下这个, 没有完全读入内存
with open('in.txt') as fp_in: with open('out.txt', 'w') as fp_out: fp_out.writelines(line for i, line in enumerate(fp_in) if i != 10) |
4
Sherlockhlt OP @timonwong
能说具体点吗? |
5
Sherlockhlt OP @phuslu
这个方法我也想过,不过还是有绕个大湾的感觉 |
6
Sherlockhlt OP @zenomac
增加表示删除了没的这个标记后如何修改这个标记呢? |
7
hyq 2012-11-05 16:15:06 +08:00
@Sherlockhlt 首先得定位到那一行行首在文件中的偏移地址a,然后需要判断这行的长度l,然后需要把a+l后的所有文本全部都向前移动l个字节.
文本存储的时候不是链表结构的,我觉得在处理纯文本上已经没有更快的方法了 |
8
phuslu 2012-11-05 16:22:20 +08:00
stackoverflow 的回答如下, 不过没测试过, 不清楚性能道理如何
http://stackoverflow.com/questions/2329417/fastest-way-to-delete-a-line-from-large-file-in-python |
9
imom0 2012-11-05 16:28:23 +08:00
|
10
013231 2012-11-05 16:35:53 +08:00
我在stackoverflow.com上問了這個問題, 原地看來似乎確實沒有好辦法:
http://stackoverflow.com/q/13227970/805627 不過如果你可以把那行替換成廢棄行(比如全空格的一行), 可以使用mmap: http://stackoverflow.com/a/2330081/805627 http://www.doughellmann.com/PyMOTW/mmap/index.html @imom0 那是我問的... |
12
Sherlockhlt OP @hyq
试了下,最后要怎么改变文件大小呢? |
13
Sherlockhlt OP @013231
改成废弃一行其实直接fp.write()就可以了 |
14
hyq 2012-11-05 16:53:15 +08:00
@Sherlockhlt os.ftruncate可以
|
15
Sherlockhlt OP 感谢各位的回复,我程序已经写好了,最后总结下:
觉得还是3楼的办法比较pythonic,因为无论如何都平均要把半个文件进行IO处理,所以 直接把这个文件进行处理,这样代码比较好读,而且代价其实并不是太大(平均多1倍IO) 如果文件真的很大,就不应该用纯文本了,应该用数据库来处理才是。 |
16
Sherlockhlt OP @013231
前面说错了,write不行的,看来还是要用mmap |
17
timonwong 2012-11-05 17:27:09 +08:00
@Sherlockhlt
如果只是一行的话, mmap实现很直接,找到那一行,然后把后面的内容通过memmove移动上前并覆盖就可以了,如果文件过大,可能还要拆分执行,不过一般几个G还是没问题(32位python除外)。 |
18
BOYPT 2012-11-06 09:29:27 +08:00
os.system('sed -i 1001d %s' % filename)
|
19
Sherlockhlt OP @BOYPT
用sed缺少可移植性吧 |
20
BOYPT 2012-11-06 10:08:59 +08:00 1
@Sherlockhlt 移植性这么虚幻的东西我一般不考虑。
|
21
BOYPT 2012-11-06 10:18:25 +08:00
更科学应该使用sh模块: https://github.com/amoffat/sh
|
22
yeyu1989 2017-09-20 14:15:34 +08:00
这么多年过去了,这个问题有没有好的解决办法了呢
|
23
tqz 2020-07-23 15:38:29 +08:00
这么多年过去了,这个问题有没有好的解决办法了呢
|