ファイルI/O(二)

5631 ワード

本文は実験棟から転載する:ファイルI/O(二)

statの使用


Linuxにはコマンドがあります.ls-l、効果は以下の通りです.
$ ls -l
-rw-rw-r-- 1 shiyanlou shiyanlou 978 Sep 19 02:13 hello.c

このコマンドは、ファイルのタイプ、操作権限、ハードリンクの数、所有者、所属グループ、サイズ、変更時間、ファイル名を表示します.どのようにしてこれらの情報を得たのか、このセクションでは霧を解きます.
statの基本使用
システム呼び出しstatの役割は、ファイルの各属性を取得することです.必要なヘッダファイル:

  • 関数のプロトタイプ:
    int stat(const char \* path, struct stat \* buf)
    

    機能:ファイルまたはディレクトリのプロパティを表示します.パラメータpathが指すファイルのプロパティを、パラメータbufが指す構造にコピーします.パラメータ:
  • path:プロパティを表示するファイルまたはディレクトリのフルパス名.
  • buf:属性を格納するための構造体を指す.statが正常に呼び出されると、bufの各フィールドに各属性が格納されます.
  • struct statは、システムヘッダファイルで定義された構造体であり、
  • と定義されている.
    struct stat {
        dev_t       st_dev;
        ino_t       st_ino;
        mode_t      st_mode;
        nlink_t     st_nlink;
        uid_t       st_uid;
        gid_t       st_gid;
        dev_t       st_rdev;
        off_t       st_size;
        blksize_t   st_blksize;
        blkcnt_t    st_blocks;
        time_t      st_atime;
        time_t      st_mtime;
        time_t      st_ctime;
    };
    
  • st_ino:ノード番号
  • st_mode:ファイルタイプとファイルアクセス権限がこのフィールドに符号化された
  • st_nlink:ハード接続数
  • st_uid:所有者のユーザID
  • st_gid:属するグループのグループID
  • st_rdev:デバイスファイルのプライマリデバイス番号、セカンダリデバイス番号は、このフィールドの
  • に符号化される.
  • st_size:ファイルのサイズ
  • st_mtime:ファイルが最後に変更された時間の戻り値:正常に0を返します.失敗は-1
  • を返します.
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main(int argc, char **argv)
    {
        struct stat     buf;
        if(argc != 2) { 
            printf("Usage: stat "); 
            exit(-1); 
        }
        if(stat(argv[1], &buf) != 0) { 
            printf("stat error."); 
            exit(-1); 
        }
        printf("#i-node:    %ld
    ", buf.st_ino); printf("#link: %d
    ", buf.st_nlink); printf("UID: %d
    ", buf.st_uid); printf("GID: %d
    ", buf.st_gid); printf("Size %ld
    ", buf.st_size); exit(0); }

    ファイルタイプの判定
    前のセクションのstruct statにst_というフィールドがあります.modeは、ファイルタイプとファイルアクセス権を取得するために使用できます.このフィールドから必要なファイル情報を復号することを学びます.st_modeのファイルタイプマクロ定義:
    マクロ定義
    ファイルの種類
    S_ISREG()
    標準ファイル
    S_ISDIR()
    ディレクトリファイル
    S_ISCHR()
    文字デバイスファイル
    S_ISBLK()
    ブロックデバイスファイル
    S_ISFIFO()
    有名なパイプファイル
    S_ISLNK()
    ソフトリンクファイル
    S_ISSOCK()
    ソケットファイル
    上記の例を修正します.
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main(int argc, char **argv)
    {
        struct stat buf;
        char * file_mode;
        if(argc != 2) {
            printf("Usage: stat 
    "); exit(-1); } if(stat(argv[1], &buf) != 0) { printf("stat error.
    "); exit(-1); } if (S_ISREG(buf.st_mode)) file_mode = "-"; else if (S_ISDIR(buf.st_mode)) file_mode = "d"; else if (S_ISCHR(buf.st_mode)) file_mode = "c"; else if(S_ISBLK(buf.st_mode)) file_mode = "b"; printf("#i-node: %ld
    ", buf.st_ino); printf("#link: %d
    ", buf.st_nlink); printf("UID: %d
    ", buf.st_uid); printf("GID: %d
    ", buf.st_gid); printf("Size %ld
    ", buf.st_size); printf("mode: %s
    ", file_mode); exit(0); }

    ファイル権限の判定
    ファイルタイプはライセンス設定とともにst_に符号化されるmodeフィールドでは、上記と同様に、システムによって提供されるマクロのセットが復号を完了する必要があります.
    マクロ定義
    ファイルの種類
    S_ISUID
    実行時、ユーザIDを設定
    S_ISGID
    実行時にグループIDを設定
    S_ISVTX
    テキストの保存
    S_IRWXU
    所有者の読み取り、書き込み、および実行権限
    S_IRUSR
    所有者の読み取り権限
    S_IWUSR
    所有者の書き込み権限
    S_IXUSR
    所有者の実行権限
    S_IRWXG
    ユーザー・グループの読み取り、書き込み、および実行権限
    S_IRGRP
    ユーザー・グループの読み取り権限
    S_IWGRP
    ユーザー・グループの書き込み権限
    S_IRWXO
    その他の読み取り、書き込み、実行権限
    S_IROTH
    その他の読み取り権限
    S_IWOTH
    その他の書き込み権限
    S_IXOTH
    その他の実行権限

    ディレクトリアクション


    ファイルではなくディレクトリがターゲットの場合、ls-lの結果はディレクトリの下のすべてのサブエントリの情報を表示します.どのようにディレクトリ全体を巡りますか?
    ディレクトリを開く
    必要なヘッダファイル:

  • 関数のプロトタイプ:
    DIR * opendir(const char * name)
    

    機能:opendir()パラメータnameで指定したディレクトリを開き、DIR*の形態のディレクトリストリームの戻り値を返します.ディレクトリストリームを正常に返します.失敗はNULLを返します
    ディレクトリの読み込み
    関数のプロトタイプ:
    struct dirent * readdir(DIR * dir)
    

    機能:readdir()は、パラメータdirディレクトリストリームの次のサブエントリ(サブディレクトリまたはサブファイル)の戻り値を返します.構造体が指すポインタ、エラー、またはディレクトリを読み終えた後、NULL関数を返して正常に戻った構造体のプロトタイプは、次のとおりです.
    struct dirent {
       ino_t   d_ino;
       off_t   d_off;
       unsigned short  d_reclen;
       unsigned char   d_type;
       char    d_name[256];
    };
    

    ここでd_nameフィールドは、サブエントリを格納する名前です.
    ディレクトリを閉じる
    関数のプロトタイプ:
    int closedir(DIR * dir)
    

    機能:closedir()dirが指すディレクトリストリームの戻り値を閉じる:0を正常に返す;エラーの原因はerrnoにあります.
    総合的な例を学びましょう.
    #include 
    #include 
    #include 
    int main(int argc, char *argv[])
    {
        DIR *dp;
        struct dirent *entp;
        if (argc != 2) {
            printf("usage: showdir dirname
    "); exit(0); } if ((dp = opendir(argv[1])) == NULL) { perror("opendir"); exit(-1); } while ((entp = readdir(dp)) != NULL) printf("%s
    ", entp->d_name); closedir(dp); return 0; }