この記事では、Linux ファイル IO の基本機能について簡単に説明します。ファイル IO は、システム コール IO とも呼ばれます。これは、「ユーザー モード」で実行されているプロセスとハードウェア間の対話のためにオペレーティング システムによって提供される一連のインターフェイスです。オペレーティング システムのカーネルはユーザー プログラム用に予約されており、Linux システムはオペレーティング システムの構造に従って、上からユーザー プロセス、Linux カーネル、物理ハードウェアに分かれています。Linux カーネルには、システム コール インターフェイスとカーネル サブシステムの 2 つの部分が含まれています。Linux カーネルは、下位では物理ハードウェアを管理し、上位ではオペレーティング システムとアプリケーションにインターフェイスを提供する、「過去と未来をつなぐ」という重要な位置にあります。
以下に、一般的なファイル操作の open、read、write、lseek、close 関数を紹介します。
開ける
ヘッドファイル
#include <sys/stat.h>
#include <fcntl.h>関数
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);ファイルをオープンし、ファイルを操作するためのファイル記述子を取得する
関数パラメータ pathname: ファイルに対応する文字列オープンするパス 最初のアドレス フラグ O_RDONLY 読み取り専用 O_WRONLY 書き込み専用 O_RDWR 読み取り/書き込み
上記 3 つの定数のうち 1 つだけを指定できます (以下の複数の定数は | (または演算) で接続されます)
O_CREAT 作成するファイルが存在しません (第 3 パラメータに渡すにはオープンが必要です)
O_TRUNC ファイルは存在しますが、次のように切り詰められます。 0 (0にクリア)
O_APPEND オープンするために追加
O_ASYNC 非同期IO
O_NONBLOCK ノンブロッキングIO
O_EXCL ファイルが存在するかどうかを検出
戻り値
新しいファイル記述子を正常に返す 失敗した
戻り値 -1
近い
ヘッドファイル
#include <unistd.h>
関数
int close(int fd);
関数が
ファイル記述子
パラメータ
を閉じるファイル記述子の
戻り値
成功 戻り値 0
失敗 戻り値 -1
書く
ヘッドファイル
#include <unistd.h>
関数
ssize_t write(int fd, const void *buf, size_t count);
機能
ファイルディスクリプタに対応するファイルに、buf で始まるデータを count バイト書き込みます
パラメータ
fd: ファイルディスクリプタ
buf: データ空間の先頭アドレスを格納
count: write入力されたバイト数を
返します
。成功した場合は実際に書き込まれたバイト数を返します。
失敗した場合は -1 を返します。
読む
ヘッドファイル
#include <unistd.h>
関数
ssize_t read(int fd, void *buf, size_t count);
関数
ファイル記述子から count バイトを読み取り、buf が指す空間に配置します
パラメータ
fd: ファイル記述子
buf: データ空間の最初のアドレスを格納します
count:読み取りデータの最大バイト数
の戻り値。
成功した場合は実際に読み取られたバイト数が返されます。
失敗した場合は -1 が返され、
ファイルの終わりを読み取ると 0 が返されます。
ここで、上で紹介した 4 つの関数インターフェイスを使用して、ファイルのコピーを実装します。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
int fd_src = 0;
int fd_dst = 0;
char tmpbuff[1024] = {0};
ssize_t nret = 0;
fd_src = open("src.jpg",O_RDONLY);//打开文件只读
fd_dst = open("dst.jpg",O_WRONLY | O_TRUNC | O_CREAT,0664);/*打开文件读写、截断为0、如果文件不存在则创建 mode(110 110 100)*/
if(-1 == fd_dst || -1 == fd_src)
{
perror("fail to open");
return -1;
}
while (1)
{
nret = read(fd_src, tmpbuff, sizeof(tmpbuff));//读到多少返回到nret
if(0 >= nret)//如果nret不大于0则说明读到末尾
{
break;
}
write(fd_dst,tmpbuff,nret);//上面nret为多少就写多少
}
close(fd_src);
close(fd_dst);//关闭两文件
return 0;
}
探す
ヘッドファイル
#include <unistd.h>
関数
off_t lseek(int fd, off_t offset, int whence);
関数
再配置ファイル記述子オフセット
パラメータ
fd: ファイル記述子
オフセット: オフセット
>0 後方オフセット
<0 前方オフセット
whence: SEEK_SET ファイル 現在位置のファイル
先頭の SEEK_CUR SEEK_ENDファイルの最後戻り値成功した場合はオフセットを返し、失敗した場合は -1 を返します。
以下は、lseek 関数を使用してファイルを操作する方法です。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main(void)
{
int fd = 0;
off_t len = 0;
fd = open("file.txt", O_WRONLY | O_CREAT | O_TRUNC, 0664);
if (-1 == fd)
{
perror("fail to open");
return -1;
}
len = lseek(fd, 10, SEEK_SET);//定位文件开头向后偏移10
printf("偏移量:%ld\n", len);
write(fd, "a", 1);
len = lseek(fd, -5, SEEK_CUR);//定位文件当前向前偏移5
printf("偏移量:%ld\n", len);
write(fd, "b", 1);
len = lseek(fd, 0, SEEK_SET);//定位文件开头无偏移
printf("偏移量:%ld\n", len);
write(fd, "c", 1);
close(fd);
return 0;
}
10 のオフセットは最初は 10 に位置し、a を挿入した後のオフセットは 11 であることがわかります。現在位置から左に 5 オフセットした後、印刷されるオフセットは 6 になり、最終的に 0 の先頭からオフセットされます。なので、オフセットは Shift が 0 になります。
作成したファイルを開いた後の内部挿入結果は図のとおりです(赤い部分は文字がなく、スペース\0\nではないため正常に表示できません)