Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

POCO流ファイル処理あれこれ

オープンソースC++用クラスライブラリPOCO活用講座(4)

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2008/02/28 14:00

本記事ではPOCO(C++ Portable Componentsの略)というオープンソースのC++用クラスライブラリを紹介します。今回も、6つのライブラリのうちのPOCO::Foundationライブラリから、いくつかクラスをピックアップして解説しましょう。今回のテーマは、最も基本的とも言えるファイル処理です。

目次

はじめに

 本記事ではPOCO(C++ Portable Componentsの略)というオープンソースのC++用クラスライブラリを紹介します。今回も、6つのライブラリのうちのPOCO::Foundationライブラリから、いくつかクラスをピックアップして解説しましょう。今回のテーマは、最も基本的とも言えるファイル処理です。

これまでの記事

  1. POCO::Netライブラリによる組み込みWebサーバの実装
  2. 5分で使えるLoggingフレームワーク - POCO::Foundation -
  3. テキスト処理もPOCOにおまかせ

対象読者

 オブジェクト指向を理解し、ネイティブC++のクラスライブラリを活用できる方を対象としています。

必要な環境

 POCOは、多様なプラットフォームで動作可能で、Windows、Mac OS X、Linux、HP-UX、Tru64、Solaris、QNXでの動作を保証しています。コンパイラは、いわゆる標準C++のコードに対応したものが必要です。POCO内部でSTLを使用しています。

 今回から、Windows Vista上の「Microsoft Visual C++ 2008 Express Edition」という環境で動作検証を行いました。Visual Studio 2008になって、Express EditionでもプラットフォームSDKの別途インストールは不要になっています。Win32 APIを利用する場合はインストールが楽になりました。

POCOでのファイル処理 1

 ファイル処理は、POCO::Foundationライブラリ内の「Filesystem」という名のパッケージにまとめられており、以下の5つのクラスが実装されています。ファイル処理はプラットフォーム(Windows、UNIXなど)に依存するものが多いのですが、記事では基本的にWindows環境のみを想定して解説します。

Filesystemパッケージに含まれるクラス一覧
クラス名概要
Fileファイル操作クラス
Pathディレクトリ操作クラス
DirectoryIteratorディレクトリ内ファイル列挙
TemporaryFile一時ファイル名取得
Globワイルドカード検索

 プラットフォームが違えば、ファイルシステムも異なります。POCOでは、複数の環境に対応するため、インターフェースと実装とが分離しており、内部の実装部分でプラットフォームごとに分かれています。そのため、利用する側では特にプラットフォームの違いを意識する必要はありません。ただし、中にはプラットフォームに依存した振る舞いをする関数もあります。例えばUNIX系環境では、ファイルにアクセス権として「読込可」「書込可」「実行可」の属性を付与することができます。それに対応してsetExecutableという実行許可を付加するメンバ関数がPoco::Fileクラスにあります。Windowsではファイルにそのような属性はありませんので、関数の定義はありますが処理は何も実装されていません。

 各クラスをリファレンス的に詳しく解説していっても退屈ですので、それはPOCOのドキュメントに譲ることにし、ここではクラスの特徴的なポイントをサンプルコードと合わせて解説することにしましょう。

File

 基本的なファイル操作クラスです。ただ、MFCでのCFileクラスのようなファイルをオープンして読み書きするクラスとは少し趣が異なっています。メンバ関数として用意されているのは、ファイルのコピーやリネーム、空のファイル作成など、ファイルを外部的に操作するものばかりです。その上、通常のファイルだけでなく、ディレクトリから生成することもできます。ディレクトリかどうかを返すメンバ関数isDirectory、ディレクトリを作成するメンバ関数createDirectoriesなどが用意されています。

 それでは、ファイルを読み書きする処理は、POCOのクラスでは実装されていないのでしょうか?

 実はファイルの読み書きに関しては、POCOではストリームとして処理するようになっているのです。ストリームを操作するクラスは、けっこう豊富に用意されているので、それはまた後ほど解説することにしましょう。Poco::Fileクラスのサンプルコードを以下に示します。

Poco::Fileクラスのサンプルコード
#include <iostream>
#include <Poco/File.h>
#include <Poco/Exception.h>

int _tmain(int argc, _TCHAR* argv[])
{
    Poco::File tmp( "c:\\test.txt" );

    // ファイルコピー
    tmp.copyTo( "c:\\temp" );

    // ファイル削除
    tmp.remove();

    // a,b,cのディレクトリを一度に作成する
    Poco::File dir1( "c:\\a\\b\\c" );
    dir1.createDirectories();

    dir1 = "c:\\a";  // 代入演算子が定義されており、この記述が可能

    try {
        // 削除
        dir1.remove();
    }
    catch( Poco::Exception& ex )
    {
        // c:\\aが空でないと削除できないが
        std::cout << ex.displayText() << std::endl;
    }

    // こうすれば、C:\a以下全サブディレクトリごと削除できる
    dir1.remove( true );

    Poco::File dir2( "C:\\Lib\\poco" );

    // Poco::Fileのvectorを用意
    typedef std::vector<Poco::File> fary;
    fary files;

    // dir2ディレクトリ以下のファイルを取得
    dir2.list( files );

    // ファイル列挙(ディレクトリも含まれる)
    for ( fary::iterator it = files.begin(); it != files.end(); ++it )
        std::cout << (*it).path() << std::endl;

    return 0;
}

 コメントを追っていけば分かると思いますが、いくつか補足をしておきます。

Poco::File.remove

 Poco::File.removeでは、クラス自身が保持しているファイルを削除します。引数はリカーシブ(再帰)オプションで、デフォルトではfalseになっています。クラスがディレクトリを示していて、引数がtrueの場合はディレクトリ内のファイルの有無にかかわらずディレクトリごと削除されます。

Poco::File.list

 Poco::File.listは、クラスが保持しているディレクトリ配下のファイルを取得します。サンプルコードではPoco::File型のvectorで取得しています。クラス自身がディレクトリを示していない場合は例外が送出されます。

 Poco::File型だけでなく、std::vector<std::string>を引数で指定することもできます。その場合はファイル名のみを文字列として取得することになります。Poco::File型だけでもいいように思えますが、実はPoco::Fileにはファイル名を参照するメンバ関数がないのです。サンプルコードのpathのようにフルパス名を返すメンバ関数しかありません。ファイル名だけを取り出したいときは、次のPoco::Pathクラスを使うことになります。

 なお、いずれの場合も取得したファイルにはサブディレクトリが含まれます。ただし、ファイルを列挙するCランタイム関数(_findfirst_findnext)や、Win32 APIのFindFirstFileFindNextFileとは異なり、自分「.」や親ディレクトリ「..」は含まれません。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • WINGSプロジェクト 高江 賢(タカエ ケン)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2017年5月時点での登録メンバは52名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂き...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XMLD...

バックナンバー

連載:オープンソースC++用クラスライブラリPOCO活用講座
All contents copyright © 2005-2018 Shoeisha Co., Ltd. All rights reserved. ver.1.5