差分FTPを考える(8 – 組み込み
差分のみ転送するように修正しました。
findを-lsをつけて実行すると以下のように出力します。
1125899906910144 4 -rwx------ 1 Admin None 1094 2月 21 2013 test.lnk
0番目がiノード、10番目がファイル名になっています。
あとは前述した、リトライと削除されてしまったファイルのハッシュキーの削除が追加されています。
更に前述したように考慮されていない点が2点あります。
- ファイルが削除されても既にアップされたファイルは消さない
- ディレクトリが削除されても、削除しない
ファイルについてはハッシュのキーを比較すればできそうですが、
ディレクトリについてはちょっと難しいかもしれません。
ディレクトリについては妥協しても良いかもしれませんが。
#!/usr/bin/perl use strict; use Net::FTP; use Storable qw(nstore retrieve); use Cwd; my $cwd = getcwd(); # 引数を読み取る if ($#ARGV ne 5 ){ print "引数が誤っています。\n"; print "$0 [hostname] [user] [password] [fromdir] [todir] [dat]\n"; exit 1; } my $hostname=$ARGV[0]; my $user =$ARGV[1]; my $password=$ARGV[2]; my $from =$ARGV[3]; my $to =$ARGV[4]; my $bdata =$ARGV[5]; my $from_dir =`dirname $from`; my $from_base=`basename $from`; my $ret; chomp $from_base; chomp $from_dir; # 前回の状態を読み込む #### Read ########################### my %btmp; if ( -f $bdata ){ %btmp=%{ retrieve(${bdata}) }; } ##################################### # 転送予定のフォルダのリストを取る my $ret=chdir("$from"); my %ftmp; open (FNAME,qq(find . -type f -ls|)); while (<FNAME>){ chomp; my $inode =(split(" ",$_))[0]; my $filepath=(split(" ",$_))[10]; my $dn=`dirname $filepath`; my $fn=`basename $filepath`; chomp($dn); chomp($fn); $ftmp{$filepath} = $inode; } # 接続 my $ftp= Net::FTP->new(qq($hostname), Debug => 0); $ftp->login($user , $password ); $ftp->binary(); $ret=$ftp->cwd($to ); if($ret eq ''){ print qq(cwd error \[$to\]\n); exit 1; } # ディレクトリをfindで検索してput先にmkdirする。 open (DIRNAME,qq(/usr/bin/find . -type d|)); while (<DIRNAME>){ chomp; $ftp->mkdir($_); } close DIRNAME; # ファイルをfindで検索してput先にputする。 open (FNAME,qq(/usr/bin/find . -type f -ls|)); while (<FNAME>){ chomp; my $inode =(split(" ",$_))[0]; my $filepath=(split(" ",$_))[10]; # 前回と同じかどうかをチェック if ( $btmp{$filepath} eq $ftmp{$filepath} ){ next; } my $dn=`dirname $filepath`; my $fn=`basename $filepath`; chomp($dn); chomp($fn); $ftp->cwd($dn); if($ret eq ''){ print qq(cwd error \[$dn\]\n); exit 1; } print &getdate . qq( [put] $filepath\n); # エラーになることがある. for my $var (3,5,10,30,60){ #ファイルが無くなることがある? if ( -f $filepath ){ $ret=$ftp->put($filepath); if($ret eq ''){ print qq(put error \[$filepath\] sleep $var\n); sleep $var; }else{ if ( $var ne 3 ){ print qq(retry \[$filepath\] ok.\n); } last; } }else{ print qq(not found \[$filepath\] skip.\n); delete $ftmp{$filepath}; last; } } $ftp->cwd($to); } close FNAME; #### Write ########################## chdir $cwd; nstore \%ftmp , $bdata; ##################################### sub getdate{ my ($sec,$min,$hh,$dd,$mm,$yy,$weak,$yday,$opt) = localtime(time); #my $t="$yy/$mm/$dd $hh:$min:$sec"; my $t=sprintf("%04d/%02d/%02d %02d:%02d:%02d",$yy+1900,$mm+1,$dd,$hh,$min,$sec); return $t; } 1;
ディスカッション
コメント一覧
まだ、コメントがありません