Linuxのopen(低水準入出力)の使い方やfopenとの違いをまとめていく
調べていたら思ったよりはまってしまったので、これを機にopen
に関してまとめておく。
open の基礎知識
open
とは、Unixにおける入出力システムを提供してくれる関数のこと。早い話が、C言語のfopen
の低レベルバージョンの関数。
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode);
例えば、以下のように書くことで、test.txt
に"hello"と書き込める。
#include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <string.h> int main() { int fp = open("./test.txt", O_CREAT | O_RDWR, S_IRWXU | S_IRWXO); char *str = "hello"; write(fp, str, strlen(str)); return 1; }
openの具体的な使い方
では、open
の使い方を具体的に見ていく。
int open(const char *pathname, int flags, mode_t mode);
- 第1引数 ファイル名
- 第2引数 ファイルへのアクセスや作成に関する設定フラグ
- 第3引数 モード(0777みたいなやつ)
戻り値には、int
型のファイルディスクリプターを返す。(ディスクリプターとは、FILE *fp
みたいにファイルを識別するやつ)
int flags
第2引数について
第2引数には、必ずアクセスモードを1つ入れなければいけない。アクセスモードとは、読み込み専用とか書き込み専用とか読み書き用みたいなやつで、以下の3つが用意されている。
- O_RDONLY
- O_WRONLY
- O_RDWR
他にも第2引数には、ファイル作成フラグとファイル状態フラグを追加できる。
ファイル作成フラグとは、「O_CREAT」のようにファイルが存在しなければ追加する、と言う設定ができるもの。ファイル状態フラグとは、「O_NOFOLLOW」のように、ファイルがシンボリックリンクだった場合open
が失敗するようにする、などができるもの。(シンボリックリンクとは、ファイルの分身みたいなやつ)
ファイル作成フラグとファイル状態フラグの詳細については、「Man page of OPEN」が詳しい。
mode 第3引数について
第3引数は必須ではないが、例えば第2引数にO_CREAT
を定義してファイルが存在しない場合に新規ファイルを作成するようにした場合に、その新規ファイルのパーミッション(mode)を指定する場合に必要になる。
例えば、「S_IRWXU」と指定すると「700 ユーザー (ファイルの所有者) に読み込み、書き込み、 実行の許可」を設定できる。詳細は、「Man page of OPEN」を見ると良い。(O_CREATEの説明のちょっと下に掲載されている)
openとfopenの違いとは?
open
とfopen
の違いを列挙すると、以下の2点があげられる。
fopen
はOSに依存しないが、open
はUnix系でしか使えないfopen
の方が高速に動作する
なぜfopen
の方が高速に動作するかと言うと、fopen
ではバッファを作っており、そのバッファを通してファイルの出入力を行っているからだ。
open
ではファイルと直接やり取りをしているため、10回100回とopen
を使うと、その分だけファイルとのやり取りが生じている。一方でfopen
はバッファを作成してそのバッファが一杯になった時に、初めてファイルに入出力を行うのでopen
よりも高速に動く。
ちなみに、fopen
の優秀性に関しては、以下の記事で書かれている。(公式の解説ページがなかったけど)