[转帖]关于open的"+<"模式

| 1 Comment | 0 TrackBacks | WebBlog Articles

作者:非四。
地址:http://www.1313s.com/f/open.html

描述

很多人知道open除了<, >, >>模式外还有其他模式如"+<", 但有些人不太会用,或者说错误的用了"+<"模式。
一般我们更新文件(需要读取原内容文件)时,都先open<读取再对内容进行变化,最后open>写入。
而用+<加seek可以实现文件的读写更新,不用两次open,从而提高效率。
但值得注意的是:如果不用truncate,文件会出现你所不想要的后果。而另人遗憾的是书中说truncate不是所有平台都支持的。不过就我测试而言,Win2000/XP+Linux下都是可以的。
一切用实验来说话。具体原理可以参考perldoc或书籍。

实验

实验材料:程序目录下有一文本文件1.txt, 里面的内容为简单的“123456789”。
实验一:简单的计数器增加
原代码:


open(FH,"1.txt");
flock(FH, 1);
my $count = <FH>;
close(FH);
$count++;
open(FH,">1.txt");
flock(FH, 2);
print FH $count;
close(FH);

改写后的代码:

open(FH,"+<1.txt");
flock(FH, 2);
my $count = <FH>;
seek(FH,0,0);
print FH ++$count;
close(FH);


简单的从两次open转化为"+<"模式就是这个样子。

实验二:不用truncate的不可意料错误。

这种错误发生在后来写入的长度小于原文件的长度。
比如我们的任务是去掉1.txt中所有的1。如下代码是错误的,出现的结果不是我们想要的。

open(FH,"+<1.txt");
flock(FH, 2);
my $count = <FH>;
$count =~ s/1//sg;
seek(FH,0,0);
print FH $count;
close(FH);

我们所要的结果是23456789,而实际运行后的结果为234567899。后面多了一个9。
"+<"模式是覆盖模式,你后来输入的长度只覆盖那么长,如果原来文件的长度比输入的长度长,后面将会保留。
正确的代码为:

open(FH,"+<1.txt");
flock(FH, 2);
my $count = <FH>;
$count =~ s/1//sg;
seek(FH,0,0);
truncate(FH, 0);
print FH $count;
close(FH);

seek到文件头后将文件清空,再输入改变后的值。
当然有时候是不需要truncate的,看具体的要求具体分析。比如我们就要覆盖那么长后面的就要保留。
比如最上面的$count就不需要,因为加后的count不会小于原来的长度。

题外话

在写本文之前,我在看LeoBBSx的最新版本代码。LeoBBSx有用了+<模式(虽然不是很彻底,只部分采用),但遗憾的是没有truncate。
我没在本地做测试看它会不会出错,但我总觉得奇怪,它用这个模式的时候难道改变后的值都长于原来的值?
或许不用truncate是采用这模式不彻底的原因。

引用通告|TrackBacks (0)

本日志的TrackBack URL: http://easun.org/cgi-bin/mtos/tb_mt_41.pl/21.

本文相关评论|Comments (1)

小骆驼书里面 定长数据库 就是讲的他和pack/unpack的应用~
挺经典的
这篇也是

发表该文评论|Leave a comment

最近发表|Recent Entries

[八卦]话说修路这件事

建国路貌似又在修。根本没有办法步行。这个让我想起来一个笑话:话说某A国人来北京,在东城区丢了一枚戒指,于是乎找警察,警察告诉他尽可能的帮他找。过了几天,此人发现整个东城的马路都挖开了,于是感叹曰:北京的警察真好。看来这个笑话的地点可以换在朝阳了?是不是某人的戒指又丢了?PS: 城市规划城市规划,年年挖年年修。。。生命不休,挖路不止…

[SiteLog]Blog升级到了 Movable Type Pro 4.25

Thisi is a SiteLog of Easun's WebBlog.今天终于升级到了 Movable Type Pro 4.25 ,貌似一切顺利,也没有发现什么特别大的改动?只是 Community Pack 变成了 1.62, Professional Pack 升级成了1.3 。其他的一切顺利,模版也没有修改,我甚至连重建前台HTML的事情都没有做。。。就这样吧,继续用这个风格,等有时间了再慢慢研究吧。如果非要说有什么修改的话,就是评论的登陆方式又丰富了很多,包括…

IE脚本错误,可以尝试以下办法

IE 脚本错误是个很麻烦的问题,一般定位都是 JS 引擎 和 VB 引擎出错。但是有时间反复注册 jscript.dll 和 vbscript.dll 也不能解决问题。具体表现 部分 js 解析正常,而部分就不行,尤其是基于 Web2.0的网站。不说别的,就连 ie7/ie8 本身第一次运行向导的"保存设置"也出错。其实研究下,貌似都出现在 XML 解释上? 重新注册…