Linux 系統 IO之 open close 函數

Linux 系統 IO之 open close 函數



1. open 函數族

1.1 頭文件包含

使用 Linux IO open 函數需要包含如下頭文件:

#include <sys/types.h>
//因爲形參用到了 mode_t 文件類型(文件創建模式),所以需要包含
#include <sys/stat.h>
#include fcntl.h>

Q:額,記不住怎麼辦?
A:使用命令 man 2 open 查看其幫助手冊,在幫助手冊中有所有需要包含的頭文件。
Q:爲什麼是 man 2,此處 2 是什麼意思?
A:使用 man 命令可以查找常用的命令與系統調用的使用文檔,man 共有 9 個章節,其中第 2 章是系統調用(內核提供的函數),我們此處要查找的 open 函數正是 系統調用函數因此精確查找時需要指定章節。如果不指定章節,man命令會返回第一個找個的 openopen可能不是第 2 章的 open

1.2 函數原型

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
int creat(const char *pathname, mode_t mode);
int openat(int dirfd, const char *pathname, int flags);
int openat(int dirfd, const char *pathname, int flags, mode_t mode);

1.3 函數功能

openopenat函數均用來打開文件,如果文件不存在,則可以設置 O_CREAT flag 新建文件。
creat 函數僅可以用來創建文件,該函數完全可以由 open函數替代:
open(pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);

openopenat 之間的區別是什麼?

  1. 如果 openat 函數的 pathname 參數是絕對路徑,則參數 dirfd無效,此時 openat完全等同於 open
  2. 如果 openatopen 函數中 pathname 路徑名都是相對路徑:
  • open 函數相對於程序所在目錄
  • openat 函數則是相對於 文件描述符 dirfd 引用的目錄
  1. 如果openat 函數 pathname 是相對路徑,且 dirfd 是特殊值 AT_FDCWD 那麼此時 pathname相對於程序所在目錄

1.4 函數返回值

opencreatopenat三個函數,如果執行成功,返回值爲成功打開/創建的文件描述符;如果失敗,系統會根據錯誤類型設置errno,並且此時函數返回值爲 -1

1.5 形參解釋

  • const char *pathname:是一個字符串常量,用於指定要打開/創建文件的路徑,此路徑可以是絕對路徑亦可以是相對路徑
  • int flag:用於指定文件的讀寫權限於追加方式等。
    • O_RDONLYO_WRONLY or O_RDWD 三個讀寫權限必須選擇一個,分別表示:只讀只寫讀寫
    • 下列選項爲一些常用的配合上述讀寫權限的標誌,選擇多個使用 ** | ** 連接
選項 說明
O_APPEND 追加模式,寫至打開文件的尾部
O_CREAT 若打開文件不存在,創建一個新文件
O_TRUNC 截斷模式,可寫模式打開後該文件被清空重頭寫
O_NOCTTY 如果文件爲終端,那麼終端不可以調用open系統調用的那個進程的控制終端
O_EXCL 如果與 O_CREAT同時使用且文件存在,則返回錯誤消息
  • mode_t mode:指定文件的權限,如 0777,此時需要注意系統的 umask變量。例如我的 Ubuntu ,umask = 0002,此時 0777要與 0002的反碼進行與操作纔是最終的權限。
  • int dirfd:此處需要設計打開目錄相關的操作,該參數用於指定,當前 openat函數所要相對的路徑。
    • 包含頭文件 #include <dirent.h>
    • DIR* dir = opendir("目錄名")
    • int dir_fd = dirfd(dir)

1.6 案例程序

1.6.1 open 函數打開一個文件,若該文件不存在則新建

#include <sys/types.h>                                                                                                                                         
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h> // fclose
#include <stdlib.h> //exit
#include <stdio.h>  //perror

int main()
{
    int fd; 
    // 光標在 open 身上,2 shift + k 即可跳至幫助文檔
    
    // 打開文件,若該文件不存在則創建新文件
    fd = open("annNote", O_RDWR | O_CREAT, 0777);
    if(fd == -1){
        perror("create file");
        exit(1);
    }   
    // 關閉文件
    int ret = close(fd);
    if( ret == -1){
        perror("close file");
        exit(1);
    }   
    return 0;
}

1.6.2 openat 函數根據相對路徑打開一個文件,若不存在則新建

#include <sys/types.h>                                                                                                                                         
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h> // fclose
#include <stdlib.h> // exit
#include <stdio.h>  // perror
#include <dirent.h> // opendir closedir dirfd

int main()
{
	// 指定相對路徑
	DIR* dir = opendir("/home/annjeff");
	int dir_fd = dirfd(dir);
    int fd; 
    // 光標在 open 身上,2 shift + k 即可跳至幫助文檔
    
    // 打開文件,若該文件不存在則創建新文件
    fd = openat(dir_fd, "annNote.txt", O_RDWR | O_CREAT, 0777);
    if(fd == -1){
        perror("create file");
        exit(1);
    }   
    // 關閉文件
    int ret = close(fd);
    closedir(dir);
    if( ret == -1){
        perror("close file");
        exit(1);
    }   
    return 0;
}

2. close 函數

2.1 頭文件包含

#include <unistd.h>

2.2 函數原型

int close(int fd);

2.3 函數功能

close 函數用於關閉一個已經打開的文件描述符

2.4 函數返回值

  • 成功關閉已打開文件描述符,則返回0
  • 關閉失敗,則按錯誤設置全局變量errno,返回 -1

2.4 形參解釋

  • int fd:形參很簡單,即要關閉的已打開的文件描述符

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章