差分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;





ディスカッション
コメント一覧
まだ、コメントがありません