2010年8月19日木曜日

boost::filesystem 習作

いやー、ここんところ boost のリリースのタイミングが速い。実は、今まで使用するのを避けていたライブラリがありました。boost::filesystem です。もちろん、Version 3 のような日が来るまでは使えないと思っていたからです。
 と、そんなこんなで、晴れて boost::filesystem を使ってみる事に…。ただの exists に FindFirstFile -> FindClose せんだけでも、随分すっきり書ける。しかし、findfirst に相当する部分が無いようだ。この辺は、path_iterator と range 使ってスマートに書けって事なんだろうか? OSのFileSystemが面倒みるのと、ゴリゴリとフィルタを書くのとどっちがいいんだろう…。


#define BOOST_FILESYSTEM_VERSION 3
#include <iostream>
#include <boost/format.hpp>
#include <boost/filesystem.hpp>
using namespace std;
using namespace boost::filesystem;

namespace {
std::string make_backup_filename( const char* basename, int cnt ) {
return boost::str( boost::format( "%s.%03d" ) % basename % cnt );
}

std::string shift_and_find( const char* basename, int maxcnt ) {
std::string result = make_backup_filename( basename, maxcnt );
boost::filesystem::path p( result );
// バックアップ・カウント分のバックアップが作成されている場合
if( boost::filesystem::exists( p ) ) {
//一番古いファイルは、ベースのファイル名.001
p = make_backup_filename( basename, 1 );
boost::filesystem::remove( p );
// ベースのファイル名.00N (N >= 2) に対して
// Nをデクリメントしたファイル名にする
boost::filesystem::path n;
for( int i = 2; i <= maxcnt; ++i ) {
n = make_backup_filename( basename, i );
if( boost::filesystem::exists( n ) )
boost::filesystem::rename( n, p );
p = n;
}
} else {
// ベースのファイル名.00N (N > 0 && N < backupcount)
// で最大のものを見つける。
for( int i = maxcnt - 1; i > 0; --i ) {
p = make_backup_filename( basename, i );
if( boost::filesystem::exists( p ) ) {
p = make_backup_filename( basename, i + 1 );
break;
}
}
}
return p.generic_string();
}
}

int main(int argc, char* argv[])
{
if (argc < 2)
{
cout << "Usage: bktest basename\n";
return 1;
}

cout << shift_and_find( argv[1], 5 );

return 0;
}

0 件のコメント: