高度なUnixのプログラミング環境(APUE)-----ファイルとディレクトリ

著作権:https://blog.csdn.net/zl6481033/article/details/90772601

1はじめに

        ファイルを開いたり、ファイルを書き込み、この章では、自然とファイルシステムの他の特性を遵守します - 最後の章では、IO操作を実行するための基本的な機能は、通常のファイルIO基本的な質問を中心に行われている説明します。

2、STAT、fatat及び機能LSTAT

        この章では、次の3つの機能を説明し、情報は彼らのリターンです。

 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>

int stat(const char *pathname, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *pathname, struct stat *buf);

        パス名が与えられ、STAT機能は、この名前のファイルの構造に関連したメッ​​セージを返します。ファイルに関する情報を取得するfatat関数は記述子fdで既に開いている、LSTAT機能は、statをに似ていますが、ファイル名がシンボリックリンクに関する情報を返すLSTATシンボリックリンク、です。第二引数は、構造体へのポインタ、STATフィールドには以下の意味です。

struct stat {
    dev_t     st_dev;     /* ID of device containing file */
    ino_t     st_ino;     /* inode 号 */
    mode_t    st_mode;    /* 权限和文件类型,位图,权限位9位,类型3位,u+s 1位,g+s 1位,粘滞位(T位)1位。
                      位图是用一位或几位数据表示某种状态。许多要解决看似不可能的问题的面试题往往需要从位图着手。*/
    nlink_t   st_nlink;   /* 硬链接数量 */
    uid_t     st_uid;     /* 文件属主 ID */
    gid_t     st_gid;     /* 文件属组 ID */
    dev_t     st_rdev;    /* 设备号,只有设备文件才有 */
    off_t     st_size;    /* 总大小字节数,编译时需要指定宏 -D_FILE_OFFSIZE_BITES=64,否则读取大文件可能导致溢出 */
    blksize_t st_blksize; /* 文件系统块大小 */
    blkcnt_t  st_blocks;  /* 每个 block 占用 512B,则整个文件占用的 block 数量。这个值是文件真正意义上所占用的磁盘空间 */
    // 下面三个成员都是大整数,实际使用时需要先转换
    time_t    st_atime;   /* 文件最后访问时间戳 */
    time_t    st_mtime;   /* 文件最后修改时间戳 */
    time_t    st_ctime;   /* 文件亚数据最后修改时间戳 */
}

        STAT関数を使用して、おそらく最もLS -lコマンドです。ファイルに関するすべての情報を表示します。

3、ファイルタイプ

        ここでは、簡単な紹介をし、Linuxのファイルの種類を学習する前にオーバー接触したとき。通常のファイルとディレクトリに加えて、だけでなく、ファイルの種類のいくつか:

        (1)通常のファイル、一般的なファイルの種類を、このようなファイルは、テキストデータやバイナリデータであるかどうか、データのいくつかのフォームが含まれています。

        (2)ディレクトリのファイルを、このファイルには、情報と、これらのファイルを指し示すポインタに関連する他のファイルの名前が含まれています。

        (3)機器の特定の種類の文字、特殊なファイルシステムを。

        (4)特別なファイル、ディスク装置をブロックします。

        (5)FIFO、プロセス間通信のために、また、配管と呼ばれます。

        (6)プロセス間通信ネットワーク用ソケット。

        (7)シンボリックリンク、別のファイルを指す、このファイル。

システムは、特定のファイルタイプを決定するためにマクロアクションの数を提供しています唯一のif文で使いやすい、で渡すモードでstat構造体を使用する必要があります。

S_ISREG(m)        is it a regular file?                                   是否为普通文件

S_ISDIR(m)         directory?                                             是否为目录

S_ISCHR(m)        character device?                                       是否为字符设备文件

S_ISBLK(m)        block device?                                           是否为块设备文件

S_ISFIFO(m)       FIFO (named pipe)?                                      是否为管道文件

S_ISLNK(m)        symbolic link? (Not in POSIX.1-1996.)                   是否为符号链接文件

S_ISSOCK(m)     socket? (Not in POSIX.1-1996.)                            是否为套接字文件

図4に示すように、ユーザIDとグループIDの設定を設定します

        次のように6つ以上に関連するプロセスIDは以下のとおりです。

        

      設定されたユーザIDとグループIDビットは、ビットは2つのS_ISUIDとSISGIDを用いて試験することができる値は、st_modeの含有します。

5、ファイルのアクセス権限

        st_modeのは、アクセス権限を持つファイル、上記のファイルタイプに対するアクセス権限が含まれています。各ファイルのアクセス権限が9ビット、三つのグループ、ファイル所有者の権限、グループ権限ファイルの所有者、他のユーザの権利、および各グループの三にLinuxファイルパーミッションのように権限を持っている:すなわち、 (R)書き込み(W)を読み出して実行(X)-lファイル許可フラグLSを用いた場合に得られることができます。このシステムはまた、私たちはst_modeのから適切な許可ビットを得る手助けするマクロを提供します。

S_IRWXU       00700        mask for file owner permissions  当 st_mode & 这个宏时,计算结果将只保留 st_mode 中的文件属主权限,其它位全部被清零。注意只是将计算结果中其它位清零,并不是把 st_mode 本身的数据清零。
S_IRUSR       00400        owner has read permission
S_IWUSR       00200        owner has write permission
S_IXUSR       00100        owner has execute permission


S_IRWXG       00070        mask for group permissions
S_IRGRP       00040        group has read permission

S_IWGRP       00020        group has write permission

S_IXGRP       00010        group has execute permission


S_IRWXO       00007        mask for permissions for others (not in group)
S_IROTH       00004        others have read permission
S_IWOTH       00002        others have write permission
S_IXOTH       00001        others have execute permission

6所有権、新しいファイルとディレクトリ

        プロセスの実効ユーザIDのための新しいファイルを設定するユーザーIDは、グループIDについて、あなたは新しいファイルのグループIDとして、以下の基準のいずれかを選択することができます:

        (1)新しいファイルのグループIDは、プロセスの実効グループIDとすることができます。

        新しいファイルのグループID(2)は、そのディレクトリのIDに設定することができます。

7、アクセス機能

#include <unistd.h>
 
int access(const char *pathname, int mode);

        現在のプロセスのパス名、ファイルモードのパーミッション成功リターン0、それ以外のリターン1、およびエラー番号を設定するためのテストがあります。パス名は、テストへのシンボリックリンクですが、シンボリックリンクファイル自体を展開しない場合。次のようにモードが選択できます。

モードの説明
R _ OKテストは許可読み
W _ OKテスト書き込み権限
Xに_ OKテスト実行許可を
F _ OKテストファイルが存在する場合

8、umaskの機能

#include <sys/types.h>
#include <sys/stat.h>
 
mode_t umask(mode_t mask);

        ファイルモード、前回値と戻り、umaskの値の大きい、小さい権限を設定するためのプロセスをマスキング。umaskの(1)コマンドが機能パッケージを使用することです。パラメータは次のようにして構成ビットをマスクするか、または複数の動作モードを指定するビットで使用されてもよいです。

st_modeのシールド 意味

S_IRUSR

S_IWUSR

S_IXUSR

読み込み所有者

書き込み所有者

所有者の実行

S_IRGRP

S_IWGRP

S_IXGRP

これは、グループの読みであります

これは、グループ書き込みであります

これは、実行のセットです

S_IROTH

S_IWOTH

S_IXOTH

その他の読書

その他の書き込み

その他の幹部

9、chmodコマンドの機能とfchmode

#include <sys/stat.h>
 
int chmod(const char *path, mode_t mode);
int fchmod(int fd, mode_t mode);

        chmodコマンドの機能は、開いているファイルを操作fchmod、指定されたファイルのファイルアクセス許可、chmodコマンド操作のための機能の既存のファミリを変更します。ファイルのパーミッションビットを変更するためには、プロセスの実効ユーザIDがファイルの所有者と同じでなければならない、またはプロセスがスーパーユーザ権限を持っている必要があります。ビットごとのOR演算として一定のパラメータ・モード。chmodコマンドのchmodコマンドは、機能パッケージを使用することです。

10ビットスティック

        UNIXの以前のバージョンでは、このビットがセットされている実行ファイル場合スティック位置と呼ばれる場所は、プログラムの最初の実行と終了、交換プログラム領域に格納されているテキストのボディがあります。プログラムを実行するとき、これはメモリ領域に、それより早く次回になります。しかし、今のUNIXページキャッシュ技術を使用し、頻繁に使用されるデータはメモリに常駐し、そのスタックビット弱い、弱いの効果ことができます。

11、chownコマンド、fchown、lchown機能

        chownコマンドは、ファイルのユーザーIDとグループIDを変更します。

#include <unistd.h>

int chown(const char *path, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);
int lchown(const char *path, uid_t owner, gid_t group);

        成功リターン0、それ以外のリターン-1とセットにerrnoを変更し、ファイルの所有者を変更するために使用される関数のchownコマンド家族。ファイルの所有者のみが行うには、スーパーユーザーであることができます修正します。オブジェクト以外の三つの機能と同様の操作は、同じではありません。それにディスク容量を制限してください、ファイルの所有者を変更できません。

12、ファイルの長さ

        バイト単位での文書の長さを備えたst_size stat構造体のメンバは、このフィールドは通常のファイル、ディレクトリ、ファイルやシンボリックリンク有意義です。通常のファイルについては、ファイルの長さが0、この文書を読んで、結果のファイルの表示であってもよいです。ディレクトリのファイルの場合、ファイルサイズが通常の数である、シンボリックリンクのため、ファイルサイズがファイル名に実際のバイト数です。

13、切り捨てられたファイル

        時々、ファイルの末尾を短縮するために、ファイル内のデータの一部を切断する必要がある、あなたは機能やftruncateのを切り捨てる必要があります。

#include <unistd.h>
#include <sys/types.h>

int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);

        truncate函数族文件用于截断path所指定的文件到length个字节,如果想要清空一个文件可以在open时指定flags为O_TRUNC。如果length参数小于文件之前的长度那么length之后的数据被丢弃,如果大于,是系统而定,一般是在文件末尾用\0填充,使文件达到length的长度。

14、文件系统

        不详细看了,之前看过。大致都是用node存文件信息,用block存文件实际内容。

15、link、unlink、remove和rename函数


#include <unistd.h>
#include <stdio.h>

int link(const char *oldpath, const char *newpath);

int unlink(const char *pathname);

int remove(const char *pathname);

int rename(const char *oldpath, const char *newpath);

        linux中ln命令是用来创建文件连接的,ln产生硬链接。ln -s产生符号链接。两者的区别,硬链接的inode没有改变,inode号是文件的唯一标识,所以硬链接没有产生新文件。符号链接产生了新的inode号,产生了新的文件,但是不分配硬盘块。符号链接可以跨分区,可以为目录文件建立符号链接。link和ulink函数用于创建和删除符号链接。ulink删除目录项,并且将pathname所引用的文件连接计数减1,如果该文件还有其他连接,仍可以通过其他链接获取文件的数据。只有当文件的连接计数达到0时,该文件的内容才可以被删除,另外一个最值删除文件内容的条件-只要有进程打开了该文件,其内容也不能删除。ulink这种特性经常被程序用来确保即使是在程序崩溃时,它创建的临时文件也不会遗留下来。用open或creat创建一个文件,然后立即调用unlink,因为文件是打开的,所以不会删除内容,只有进程关闭改文件会终止时,该文件内容才会被删除。

        remove相当于rm命令,是使用unlink,rmdir函数封装的,它在删除文件的时候其实没有将文件的数据块从磁盘上移除,而是在被删除的文件没有任何进程引用时才将数据块释放。rename函数用于重命名文件或目录。对于文件remove的功能与unlink相同,对于目录remove的功能与rmdir相同。

        文件或目录用rename函数更名。

16、符号链接

        符号链接是对一个文件的间接指针,与上一节所述的硬链接有所不同,硬链接直接指向文件的i节点,引进符号链接是为了避免一些硬链接的限制:a)硬链接通常要求连接和文件处于同一文件系统。b)只有超级用户才能创建到目录的硬链接。而符号链接以及它指向什么没有文件系统限制,任何用户都能创建指向目录的符号链接。

        当使用以名字引用一个文件的函数时,应该了解该函数是否处理符号链接功能,也就是是否跟随符号链接连接到它所连接的文件。

17、symlink和readlink函数

 #include <unistd.h>

 int symlink(const char *target, const char *linkpath);
ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);

        symlink函数创建一个指向target的新目录项linkpath,创建此符号连接时,并不要求target存在,并且两个也不需要在同一个文件系统中。readlink函数组合了open read close 所有操作,如果此函数成功,则返回读入buf的字节数。在buf中返回的符号链接的内容不以null字符终止。

18、文件的时间

        每个文件有三个时间字段,如下表:

19、utime函数

#include <sys/types.h>
#include <utime.h>

int utime(const char *filename, const struct utimbuf *times);

struct timeval {
          long tv_sec;        /* seconds */
          long tv_usec;       /* microseconds */
           };


        一个文件的存取和修改时间可以用utime函数更改,所用结构如上图。

20、mkdir和rmdir函数

//mkdir - create a directory

#include <sys/stat.h>
#include <sys/types.h>

int mkdir(const char *pathname, mode_t mode);


//rmdir - delete a directory

#include <unistd.h>

int rmdir(const char *pathname);

        与mkdir和rmdir命令一样,用来创建和删除目录,rmdir只能删除空目录,如果要删除费空目录,需要自行递归实现。对目录而言至少需要有执行权限。

21、读目录

        对目录的写和执行权限决定了能否在该目录中创建新文件以及删除文件,并不表示能写目录本身。所谓的读目录其实是读出目录中文件列表,对目录的访问分两种方式:glob和xxxdir函数族,这里主要介绍xxxdir函数族。

//opendir, fdopendir - open a directory

#include <sys/types.h>
#include <dirent.h>

DIR *opendir(const char *name);
DIR *fdopendir(int fd);


//readdir - read a directory

#include <dirent.h>

struct dirent *readdir(DIR *dirp);


//closedir - close a directory

#include <sys/types.h>
#include <dirent.h>

int closedir(DIR *dirp);


//telldir - return current location in directory stream

#include <dirent.h>

long telldir(DIR *dirp);


//seekdir  - set the position of the next readdir() call in the directory stream.

#include <dirent.h>

void seekdir(DIR *dirp, long loc);

        opendir函数用于打开一个目录,返回一个指向目录的结构体指针。

        readdir函数用于读取目录项,每次调用返回一个目录项,循环调用就可以读出一个目录中所有目录项,返回NULL标书目录中目录项读取完毕。

        closedir用于回收资源和open成对使用。而telldir和seekdir用来定位目录项位置指针。

22、chdir、fchdir和getcwd函数

// chdir, fchdir - change working directory
 
 #include <unistd.h>
 
 int chdir(const char *path);
 int fchdir(int fd);

 char *getcwd(char *buf, size_t size);

        chdir和fchdir用于改变进程的工作目录,参数path和fd表示要修改的目标目录。cd命令就是用这个函数封装的。getcwd函数用于获取当前工作路径的绝对路径,pwd命令就是用该函数封装的。

23、特殊块设备

        st_dev和st_rdev字段很容易引起混淆。每个文件系统都是由主次设备号为人所知,设备号所用的数据类型是基本系统数据类型dev_t。通常可以使用定义的宏,major和minor来获取主次设备号。系统中每个文件名的st_dev是文件系统的设备号,只有字符特殊文件和块特殊文件才有st_rdev值,这个值包含实际设备的设备号。

24、sync和fsync函数

 #include <unistd.h>

 void sync(void);

 int fsync(int fd);

        sync将所有修改过的块的缓存排入写队列,然后返回,并不等待实际IO操作结束。系统精灵进程一般隔30秒调用一次sync函数,保证定期刷新内核的块缓存,命令sync也调用sync函数。fsync只引用单个文件,有文件描述符指定。等待IO结束返回。可用于数据库这样的应用,确保修改过的块立即写到磁盘上。

25、文件存取位小结

        已经说明了所有文件的存取许可位,某些位有多种用途。如下表:

       

       

26、小结

        围绕stat函数,介绍stat结构体中的每一个成员。对unix文件的各个属性有所了解。

おすすめ

転載: blog.csdn.net/zl6481033/article/details/90772601