首页 > 学技术 > 技术网文 > Perl > 正文

[精彩] 请教:PERL来生成文本数据最安全的方法??


来源 chinaunix.net kuqin整理

最近用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平台沒用過...:)




原文链接:http://bbs.chinaunix.net/viewthread.php?tid=174478
转载请注明作者名及原文出处



收藏本页到: