Unixファイルとi/oストリーム


1.unixファイル構造について
Unix/linuxファイルシステムでは、すべてファイルで、ディレクトリはファイルで、デバイスはファイルで、ファイルはファイルです......ファイルにはファイルの各プロパティが必要です.unixではstat関数ファミリーを使用してファイルプロパティを取得できます.stat関数を使用して取得したノードファイルはstruct stat*bufが指すメモリに格納されます.
#include 

   

    int

    fstat(int fildes, struct stat *buf);



    int

    lstat(const char *restrict path, struct stat *restrict buf);



    int

    stat(const char *restrict path, struct stat *restrict buf);



    int

    fstatat(int fd, const char *path, struct stat *buf, int flag);




    struct stat { /* when _DARWIN_FEATURE_64_BIT_INODE is NOT defined */

        dev_t    st_dev;    /* device inode resides on */

        ino_t    st_ino;    /* inode's number */

        mode_t   st_mode;   /* inode protection mode */

        nlink_t  st_nlink;  /* number of hard links to the file */

        uid_t    st_uid;    /* user-id of owner */

        gid_t    st_gid;    /* group-id of owner */

        dev_t    st_rdev;   /* device type, for special file inode */

        struct timespec st_atimespec;  /* time of last access */

        struct timespec st_mtimespec;  /* time of last data modification */

        struct timespec st_ctimespec;  /* time of last file status change */

        off_t    st_size;   /* file size, in bytes */

        quad_t   st_blocks; /* blocks allocated for file */

        u_long   st_blksize;/* optimal file sys I/O ops blocksize */

        u_long   st_flags;  /* user defined flags for file */

        u_long   st_gen;    /* file generation number */

    };
struct stat , man , , 。
a. st_mode
ファイルタイプとアクセス権を表します.
umask設定ファイル作成時のデフォルトpermission
chmod
fchmod
chown
fchown
lchown
 
b. st_ino
st_inoはinodeノード番号を表し、unix/linuxシステムでは、ファイルごとにinodeポインタを割り当てます.このinodeポインタは、ファイルに格納されているメモリブロックblocksのセットを指し、1つのblockが4 kで、私たちのファイルに7 kのファイルが保存されている場合、オペレーティングシステムはこのファイルに2つのblockと1つのinodeを割り当て、inodeはこの2つのblockのインデックスです.
 
c. st_nlink
リンクカウントについては、具体的なファイルとディレクトリで議論する必要があります.ファイルにとってst_nlinkは、そのファイルinodeを指すディレクトリ項目数を表し、ハードリンク数(hard link)とも呼ぶことができますが、これは何を意味しますか?/usr/bin/ディレクトリの下にファイルf_があるとします.nlink,f_nlinkのinode番号は1553で、このとき/usr/binディレクトリ項目のうち必ず1つのディレクトリ項目が(1553,f_nlink)、このときf_nlinkのst_nlinkは1です.lnコマンドを使用してf_にnlinkが/usr/ディレクトリにハードリンクを作成すると、/usr/ディレクトリにも必ず1つのディレクトリ項目が(1553,f_link)、/usr/および/usr/bin/が1553というinodeを指すディレクトリがあり、このときf_nlinkのst_nlinkは2(ハードリンク数は2)です.このとき/usr/bin/ディレクトリでf_nlinkを削除すると(unlinkまたはrmを使用)では、f_nlinkのリンク数は1減少しますが、inodeは依然として存在し、/usr/ディレクトリの下からもf_nlinkファイルにアクセスできます.リンク数が0に減少した場合にのみ、f_nlinkのinodeを削除し、ファイルを完全に削除してメモリを解放します.ここでは、ソフトリンクについて話すために拡張する必要があります.ソフト接続では、ボリュームが削除されると、コピーはアクセスできません本体.
 
ディレクトリの場合、1つのディレクトリ・アイテムの下にいくつかのファイルまたはサブディレクトリがある場合、リンク数は数です(.と...を含む).
 
ハードリンクには2つの制限があります.(1)ディレクトリにハードリンクを作成することは許されず、ループが発生し、ディレクトリを巡るときにデッドサイクルに陥ることを防止します.(2)同じファイルシステム内のファイル間でしかハードリンクを作成できません.これも理解できます.同じファイルシステムでのみinodeにアクセスできます.
 
 
2.unixファイルi/oストリームについて
Unixシステム呼び出しの面ではreadとwriteを使用してファイルを読み書きします.
#include 

ssize_t read(int fd, void *buf, size_t nbytes);
  :
fd:              
buf:                  
nbytes:        
   :
         ,           0;      -1。

ssize_t write(int fd, const void *buf, size_t nbytes);
   :
              ;    -1。

 
 
readとwriteシステムを頻繁に使用してファイルの読み書きを呼び出すと、プロセスはカーネル状態とユーザー状態の間で絶えず変換する必要があり、システムのオーバーヘッドが大きすぎる.そのためストリーム(stream)が現れ、ストリームの構造FILEはいくつかの部分:ファイル記述子fd、このストリームバッファポインタ、バッファサイズ、現在のバッファ内の文字数、エラーフラグなどを指す.私たちは通常ファイルポインタFILE*を使用してストリームを表し、個人的にはFILE*の使用はファイルシステム呼び出し関数のもう一つのカプセル化であると考えています.ストリームに関するいくつかのunix関数をまとめます.

a.オープンフロー
#include 

FILE *
fdopen(int fildes, const char *mode);

FILE *
fopen(const char *restrict filename, const char *restrict mode);

FILE *
freopen(const char *restrict filename, const char *restrict mode,
FILE *restrict stream);

 
b.クローズフロー
#include 

int
fclose(FILE *stream);

void
fcloseall(void);

c.読み書きフロー
読み書きの流れにもいくつかの方法があります.
バッファなし、すなわち、読み取り専用または1文字ずつ書くi/oストリーム.
#include 

int
fgetc(FILE *stream);

int
getc(FILE *stream);

int
getc_unlocked(FILE *stream);

int
getchar(void);

int
getchar_unlocked(void);

int
getw(FILE *stream);



int
fputc(int c, FILE *stream);

int
putc(int c, FILE *stream);

int
putc_unlocked(int c, FILE *stream);

int
putchar(int c);

int
putchar_unlocked(int c);

int
putw(int w, FILE *stream);
 
, i/o , \r 。
#include 

char *
fgets(char * restrict str, int size, FILE * restrict stream);

char *
gets(char *str);

int
fputs(const char *restrict s, FILE *restrict stream);

int
puts(const char *s);

 
直接i/oとも呼ばれ、i/o操作のたびにオブジェクトの数を読み書きします.
#include 



size_t

fread(void *restrict ptr, size_t size, size_t nitems,

FILE *restrict stream);



size_t

fwrite(const void *restrict ptr, size_t size, size_t nitems,

FILE *restrict stream);

 
ファイル記述子0,1,2とはそれぞれ標準入力,標準出力,標準エラーファイルを指すのに対し,ストリームにもstdin,stdout,stderrがある.
 
3.プロセスとファイル
1つのプロセスでファイルを開くと、プロセステーブル項目に対応するファイル記述子fdとそのポインタマッピングが割り当てられる.ポインタはファイルテーブルを指し、ファイルを開くたびにファイルテーブルが割り当てられ、ファイルテーブルにはファイルステータスフラグ(読み取り専用、書き込み専用、読み取り可能、書き込み可能)、現在のファイルオフセット量、vノードポインタが格納されます.vノードポインタはvノード情報を指し、vノードにはinodeが含まれます.
a.dup/dup 2を使用すると、fdをコピーしたり、fdを変更したりすることができ、プロセステーブル内の2つのfdが同じオープンファイルを指す場合を作成することができる.
b.1つのファイルを2回開くことができる場合、2つのプロセステーブル項目のうち、それぞれfdがファイルテーブルを指し、各ファイルテーブルには独自のファイルオフセット量があり、同期問題に関連する.
c.1つのプロセステーブルにおいて、2つのfdはそれぞれ異なるファイルを指す.