next up previous contents
Next: プロセス管理 Up: システムコールを使う Previous: 様々な装置

ファイル管理

ファイル操作もオンラインプログラムの重要な作業の一つです。ファイルの 存在やアクセス権を調べたり、所有者、グループなどの属性の設定、変更日付 の操作など入出力操作以外にやらなければならないことがたくさんあります。 例えばデータファイルを作るのに同じ名前のファイルが存在するかどうか調べ、 それが空でなければ.bakにリネームして新たにファイルを作るとか、ファイル システムの空き容量を調べファイルに書き出せるデータ量を決定するとかです。 それらのために次のようなシステムコールが用意されています。

        int access( char *path, int mode )      ファイルのアクセスモードの検査

        int stat( char *path, struct stat *buf )        ファイルステータスを得る。

        int ustat( dev_t dev, struct ustat *buf)        ファイルシステム統計の情報を得る。

        int chown( char *path, int own, int grp )       ファイルのオーナ/グループの変更

        int chmod( char *path, mode_t mode )    ファイルのモード変更

        int umask( int mask )           ファイル作成モードマスクの設定/取得

        int chdir( char *path )         ワーキングディレクトリの変更

        int mkdir( char *path, int mode )       ディレクトリ作成

        int rmdir( char *path )         ディレクトリ削除

        int unlink( char *path )                ファイルの削除

        int rename( char *path1, char *path2 )  ファイル名の変更

        int symlink( char *name1, char *name2 ) シンボリックリンク作成

        int readlink( char path, char *buf, int siz )   シンボリックリンクの値読み取り

        int utimes( char *file, struct timeval *tvp )   ファイルアクセス/変更時間設定

        int fcntl( int fd, int cmd, int arg )   ファイル記述子/フラグ/ロックの制御

これらのうちの多くのものは同じ名前のシェルコマンドとして用意されてい ますから特に必要はないと思います。詳しくはmanを見てください。fcntlにつ いてはプロセス間通信で見ます。statについてここでは上述の例(ファイル名 に.bakを付けて保存)に従ってやってみましょう。

statは/usr/include/sys/stat.hに定義されている次のような構造体にファ イルの情報を返します。

        struct  stat {

                dev_t   st_dev; //ファイルが存在するデバイスのID

                ino_t   st_ino; //Iノード番号

                mode_t  st_mode;        //ファイルモード

                short   st_nlink;       //リンクカウント

                uid_t   st_uid; //オーナのユーザID

                gid_t   st_gid; //オーナのグループID

                dev_t   st_rdev;        //デバイススペシャルファイル

                off_t   st_size;        //ファイルサイズ(バイト)

                time_t  st_atime;       //最終アクセス時間

                int     st_spare1;

                time_t  st_mtime;       //最終更新時間

                int     st_spare2;

                time_t  st_ctime;       //最終変更時間(属性変更含む)

                int     st_spare3;

                long    st_blksize;     //ブロックサイズ

                long    st_blocks;      //ブロック数

                long    st_spare4[2];

        };

いまから/data1/run0001.datというファイルを出力用に用意したいと思います。 statでファイルの情報を得ましょう。

        #include        <sys/type.h>

        #include        <sys/stat.h>



        struct stat     statbuf;

        int     st;



        st = stat( "/data1/run0001.dat", &statbuf );

        if( st == -1 )

        {       /*この場合はエラー。ファイルがないのかもしれない。*/

        }       /*errnoグローバル変数にエラーコードが書かれている。*/

        else

        {       /*ファイルが存在する。サイズを調べて0でなければ */

        }       /*renameしてバックアップする。*/

errnoがENOENTの場合はファイルが存在しません。この場合はあらたにopenす ればよいことになります。存在するが長さが0の時、すなわちstatbuf.st_size が0の時そのままopenしましょう。長さが0でないときは.bakを付けた名前に renameします。そしてあらたにopenします。

次に/data1というファイルシステムには後どれだけデータが書けるか調べま しょう。ファイルシステムの情報はustatで得られます。

        #include        <sys/types.h>

        #include        <ustat.h>



        struct ustat    ustatbuf;



        st = ustat( statbuf.st_dev, & ustatbuf );

先程のstatシステムコールで/data1/run0001.datのあるファイルシステムのID がst_devにあります。それを使って呼び出します。ustatはustat構造体に次の ような情報を返します。

        struct  ustat {

                daddr_t f_tfree;        /* 総空きブロック数 */

                ino_t   f_tinode;       /* 空きIノード数 */

                char    f_fname[6];     /* ファイルシステム名 */

                char    f_fpack[6];     /* パックされたファイルシステム名 */

        };

ustatbuf.f_tfreeに空きバイト数が書かれています。これを見ればあとどれだ けデータが書けるかわかることになります。

場合によってはあるディレクトリの中にあるファイルを一つづつ調べていき たい場合があります。システムコールではありませんが、そのためのCライブ ラリ関数のセットがあります。

        opendir あるディレクトリをサーチのために開く。

        readdir 開かれているディレクトリの中のファイルを一つ読む。

        closedir        ディレクトリを閉じる。

        rewinddir       ディレクトリサーチを巻き戻す。

        telldir ディレクトリの中の現在位置を返す。

        seekdir ディレクトリの指定位置に移動する。

readdirが返してくれるのはdirent構造体へのポインターです。dirent.hに定 義されています。ファイル名は構造体メンバーd_name、ファイル名の長さは d_namlenで与えられます。そのファイル名をstatすればディレクトリも見つけ ることができます。chdirしてさらにo pendirすればディレクトリツリーのな かをどこまでもたどることができます。



next up previous contents
Next: プロセス管理 Up: システムコールを使う Previous: 様々な装置



Kinya Hibino
Sun Jan 14 21:36:40 JST 1996