差分FTPを考える(4 – 前回のファイル情報をstoreableで保存する

一気にうまくやろうとするのは危険です。
というわけで、まずはあるディレクトリのファイルを取得して、その情報をハッシュにする方法を確立しましょう。

サンプルディレクトリを作る

とりあえずtestというディレクトリを作ってその中に適当にファイルを作ります。

  • test/1/a.txt
  • test/2/b.txt
  • test/3/c.txt

私はこんなふうに作ってみましたよ。もちろんもっと深くしたりするほうが有効です。

このディレクトリをどうやって検索するのかというと、
unixのコマンド’find’を使ってしまうのが手っ取り早いです。

open (FNAME,qq(find . -type f|));
while (<FNAME>){
    chomp;
    print qq($_\n) unless($_ eq '.');
}

perlからunixコマンドを呼ぶ方法は色々ありますが、
複数行の結果を1行ずつ処理するためにはopenを使うのが便利です。
chompしているのは改行が入ってしまうからです。除去しています。

これを実行してみると、きれいにパス付きでリストが取れることがわかると思います。

ハッシュにしてファイルに出してみる

とりあえず、
ハッシュ{’パス’}=’チェックサム,ファイルサイズ’
というハッシュをhdata.datというファイルに保存する簡単なプログラムを書いてみました。
チェックサムの結果をsplitしているのは結果が
4156328750 1577 ファイル名
のように出るからです。1番目がチェックサム値、2番めがファイルサイズです。
それをカンマ区切りでセットしています。

#!/usr/bin/perl
use strict;
use Storable qw(nstore retrieve);
use Cwd;
my $cwd = getcwd();

#----- conf --------
my $hdata='hdata.dat';
#-------------------
#### Read ###########################
my %htmp;
if ( -f $hdata ){
    %htmp=%{ retrieve(${hdata}) };
}
#####################################

# testディレクトリに移る
chdir "test";

open (FNAME,qq(find . -type f|));
while (<FNAME>){
    chomp;
    my $cksum=`cksum $_`;
    my @cksums=split( " " , $cksum );

    print qq($_\t$cksums[0],$cksums[1]\n);
    $htmp{$_} = qq($cksums[0],$cksums[1]);
}
#### Write ##########################
chdir $cwd;
nstore \%htmp , $hdata;
#####################################

実行すると hdata.dat というファイルが出来ます。
次はこのファイルがちゃんと出来ているかを確認します。

#!/usr/bin/perl
use strict;
use Storable qw(nstore retrieve);

#----- conf --------
my $hdata='hdata.dat';
#-------------------
#### Read ###########################
my %htmp;
if ( -f $hdata ){
    %htmp=%{ retrieve(${hdata}) };
}
#####################################



while( my($key , $value) = each %htmp ){
    print qq($key = $value\n);
}

保存する必要が無いので、開いているだけです。

実行すると以下のように出ます。

./3/c.txt = 4294967295,0
./2/b.txt = 2410625446,123
./1/a.txt = 4294967295,0

どうやらうまく出来ているようですね。