免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3134 | 回复: 4
打印 上一主题 下一主题

请教如何修改文件的最后一行 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-06-21 23:56 |只看该作者 |倒序浏览
我现在的方法是将文件句柄放到数组中修改最后一个[-1],想请问各位高手是否有更有效的方法?谢谢!

论坛徽章:
0
2 [报告]
发表于 2007-06-22 08:54 |只看该作者
版面搜索

Perl        请教如何修改文件的最后一行        yy_lc        0        28        2007-06-21 23:56
Perl        请问如何从文件的最后一行向第一行读起?        hotren        3        152        2007-06-13 11:28
Perl        我在读文本文件的时候,如果文件最后一行没有回车/换行,那么可能会不到最后一行        ste2008        3        196        2007-03-05 16:09
Perl        请问:如何读取文件的最后一行?        youhaorenshi        11        510        2005-08-24 14:24

论坛徽章:
0
3 [报告]
发表于 2007-06-22 22:18 |只看该作者
呵呵,有意思的问题。

抛开具体语言不谈,如何让这个操作运行的更快?

大多数有经验的程序员应该都会这样做:打开文件,移动文件指针到文件尾,然后回溯到文件中最末的换行(注意排除文件尾就是换行符的特殊情况),截断文件,写入数据。那么问题是,回溯的策略?

[ 本帖最后由 jigloo 于 2007-6-23 01:26 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2007-06-22 22:38 |只看该作者
回溯的策略应考虑的因素有:IO等待时间,系统调用次数,内存中字符串查找。
最后一项由于CPU和内存都很快,可以忽略不计。那么我们就要平衡前两项的时间。

一种直觉的办法,定义一个大小合适的缓存,比如1024,每次读取并查找。这个办法快而有效,几乎只要一次读取就可以找到换行符。经验告诉我们很少有文件一行大小超过1024。
但是考虑极端的情况,假设文件的最后一行很长很长,比1024要长很多,那么就要多次调用seek和read函数。这令人觉得会变慢(实际上我们几乎感觉不到)。

也许可以通过逐次增加回溯的步长来减少系统调用的次数,使用等比数列或菲波那切数列来逐增步长,尤其是菲波那切数列,用在这儿给人的感觉很美。可惜的是,这办法很糟糕。

论坛徽章:
0
5 [报告]
发表于 2007-06-22 23:22 |只看该作者
因为硬盘是块设备,所以当我们调用read函数读取指定大小字符时,操作系统其实读取了一个或多个block,拷贝给用户的进程空间指定大小的字符,并把这些block缓存起来。
所以,回溯的策略应该基于块的,而不是基于字符的。

这是个改进的策略:由于文件在硬盘/文件系统中并不是连续分布,并通常留有个一个不能完全填充一个block的尾部。所以我们可以先计算出这个尾部的大小(tailsize=size%blocksize),然后根据经验(唉),比如tailsize小于200的话(大多数行字符以内),tailsize+=blocksize。然后read(tailsize)。如果读出的数据没有换行符的话,再用菲波那切数列以block来逐增步长。当然得步长有个上限,不能无限逐增。

这个策略看起来挺不错,但是会放大内存中字符串查找的影响因素并引入额外的考虑因素,比如系统核态与用户态拷贝的效率。如何平衡并减少这些影响,这就又要我们思考了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP