最近用PERL写一个纯文本的留言板,但是数据常常发生丢失,PERL生成的文件如aa.dat有时会莫名其妙被系统[unix]删除,非常苦恼。
可以肯定的是,不是程序有问题。难道是系统的问题,或者PERL有什摩好的方法,所以想请教。
我已经把属性改为400,都不行!
PERL有什麽最安全的方法来生成这些文本数据呢?? :roll:
apile 回复于:2003-10-02 08:46:42
1.加上lock....
避免同時有兩個人access同一個文本..
只是如果使用量大,就會有人跟你抱怨,他不能貼東西...
不加lock..只要同時有兩個人以上,access文本就有可能把文本內容刪除..
我曾經經歷過...莫名其妙文件就不見了...所以後來改用其他方式..
猜測應該是同時有兩三個人access那的文本...其中有人出問題..造成
文本不見了...
2.利用directory與對方id+目前時間,directory名稱為日期...
將文本名稱利用(user id + time())儲存..分開儲存...
好處是兩個人可一同回覆文章..可保證不會因為兩個人同時access
一個人出錯..造成文本刪除的問題...但是數量很大的時候,
會很慢..
3.還是建議用database..:)
rocklv 回复于:2003-10-02 11:46:29
啊,原来是这样,真是非常感谢apile老大
麻辣 回复于:2003-10-02 23:49:39
#####我一直是这样用的文件锁,大家帮看看
$LOCK_EX = 2;
$LOCK_UN = 8;
open( TITLES, ">;>; $_data_path/forums$FORM{class}/$FORM{'forum'}/index" );
flock( TOPIC, $LOCK_EX );
print TITLES @test;
print TITLES "$new_id\n";
flock( TOPIC, $LOCK_UN ) ;
close(TITLES);
apile 回复于:2003-10-03 08:25:16
# Lock相關設定值
$RetryNum = 100; # 重試回數
$Interval = 0.1; # 重試的間隔時間
$EX_LOCK = 2; # 排他鎖定
$UN_LOCK = 8; # 解除鎖定
$LOCKTYPE = $EX_LOCK; # 鎖定格式為排他鎖定
$useflock = 0; # 使用flock()時設定值為1
$Lprefix = 'L-'; # 鎖定檔案的字首
#
# lock(lfh,lockfile);
# <IN>; lfh: 鎖定檔案的指標(相當於openLock指定的檔案名稱)
# lockfile :鎖定的檔案名稱
# <OUT>; true:成功 false:失敗
sub lock($$)
{
my($lfh,$lockfile) = @_;
if($useflock){
flock($lfh,$LOCKTYPE);
return 1;
}
else{
my ($retry) = $RetryNum;
while(-f $lockfile) {
select(undef,undef,undef,$Interval);
return undef if(--$retry <=0);
}
return open($lfh, ">;$lockfile");
}
}
#
# unlock(lfh,lockfile)
# <IN>; lfh :鎖定檔案的指標(相當於以openLock指定的檔案名稱)
# lockfile:鎖定檔案名稱
# <OUT>; 無
sub unlock($$)
{
my($lfh,$lockfile) =@_;
if($useflock){
flock($lfh,$UN_LOCK);
}
else{
close($lfh);
unlink($lockfile);
}
}
#
# openLock(fh,modefile)
# <IN>; fh :指標
# modefile: 包含模式的檔案名稱
#<OUT>; true of false
sub openLock(*$)
{
my($fh,$modefile) = @_;
my($lockf);
($mode,$file) = ($modefile=~/^(\+?(?:<|>;>;?)\s*?)(.+)$/);
if($file =~/(\/|\\)/){
($path,$filename) = ($file=~/^(.*[\/|\\])(.+)$/);
}
else{
$path = "";
$filename =$file;
}
return undef unless $filename;
$lockf = $path.$LPrefix.$filename;
lock($filename,$lockf) or return undef;
open($fh,$modefile)
or unlock($filename,$lockf), return undef;
return 1;
}
#
# closeUnlock
# <IN>; fh:指標
# modefile:包含模式的檔案名稱
# <OUT>; 無
sub closeUnlock(*$)
{
my($fh,$file) = @_;
if($file =~/(\/|\\)/) {
($path,$filename) = ($file=~/^(.*[\/|\\])(.+)$/);
}
else{
$path ='';
$filename = $file;
}
my($lockfile) = $path.'L-'."$filename";
unlock($filename,$lockfile);
close($fh);
}
某本書上看到的..他用了兩種方法...做lock
一種是多建立一個lock file
一種是用flock
有興趣的自行研究..可能有bug..因為我照書上抄的
而書的例子常常會出問題...:)
rocklv 回复于:2003-10-07 21:03:51
好棒啊,i like it
麻辣 回复于:2003-10-08 12:54:16
继续问个问题,文件锁在windows NTFS文件系统环境下是否可靠呢?
如果代码写成这样:
flock( TOPIC, $LOCK_EX )or die"文件加锁失败";
print TITLES @test;
print TITLES "$new_id\n";
flock( TOPIC, $LOCK_UN ) or die"文件解锁失败";
在FAT32文件系统会报错,但在NTFS下正常,返回值是1 ,是不是说明ntfs格式下文件锁很有效呢?
apile 回复于:2003-10-08 13:40:44
flock FILEHANDLE,OPERATION
Not implemented (Mac OS, VMS, RISC OS, VOS).
Available only on Windows NT (not on Windows 95). (Win32)
看..perlport
>; perldoc perlport
裡面有上面這一段...flock只有implement在windows NT上..
default是 NTFS...而FAT32..因為FAT Table配置不同..
所以應該無法使用才對...
以上只是我的猜測..上google上找也許可以看出端擬.
;剛剛看了一下google..
FAT32似乎也可以使用flock才對...、
你要不要試試看
use Fcntl qw(:flock);
然後直接使用 LOCK_EX、LOCK_UN、LOCK_SH
在flock後面...win32平台沒用過...:)
|