[APUE] 文件 I/O 之 Open/Close

前言

上一篇文章,主要講了文件描述符的基本知識(shí).這篇,我將會(huì)結(jié)合代碼,對(duì)上一節(jié)的 open,close函數(shù)進(jìn)行詳細(xì)的講解.

代碼 Git 地址 SuzhenProjects/ApueProject

常用函數(shù)復(fù)習(xí)

  • open 打開(kāi)或者創(chuàng)建一個(gè)用來(lái)讀/寫(xiě)的文件
  • read 讀取用戶指定的 Input
  • write 寫(xiě)入到指定的 Output
  • lseek 重新定位讀寫(xiě)游標(biāo)的位置
  • close 刪除(關(guān)閉)一個(gè)文件描述符

Tips: 通過(guò) man 2 <Command> 可以查詢(xún)你系統(tǒng)的這些 API 檔案

Open 函數(shù) int open(const char *path, int oflag, ...);

  • path 文件的路徑,如果文件不存在,則返回錯(cuò)誤
  • oflag 打開(kāi)文件/目錄,所使用的用戶自定義選項(xiàng)
    • O_RDONLY 只讀
    • O_WRONLY 只寫(xiě)
    • O_RDWR 讀/寫(xiě)
    • O_NONBLOCK 打開(kāi)文件時(shí)/讀取數(shù)據(jù)時(shí),不要阻塞調(diào)用
    • O_APPEND 追加模式,write的內(nèi)容被追加到文檔的末尾
    • O_CREAT 如果文件不存在,open會(huì)創(chuàng)建文件
    • O_TRUNC 截?cái)辔募?使文件長(zhǎng)度為0
    • O_EXCL 存在O_CREAT模式時(shí),如果文件存在,會(huì)返回錯(cuò)誤
    • O_SHLOCK 自動(dòng)獲取 flock 的共享鎖
    • O_EXLOCK 自動(dòng)獲取 flock的獨(dú)占鎖
    • O_NOFOLLOW 打開(kāi)文件的鏈接時(shí), 會(huì)失敗
    • O_SYMLINK 運(yùn)行打開(kāi)文件的鏈接
    • O_EVTONLY 用來(lái)監(jiān)視文件是否有改動(dòng)
    • O_CLOEXEC 標(biāo)記為close-on-exec
  • 擴(kuò)展參數(shù)
    • 可以傳入文件的權(quán)限標(biāo)志 如 0755,0666
  • 返回值 成功會(huì)返回一個(gè)正整數(shù),其余均為失敗,需要檢查errno

Close 函數(shù) int close(int fildes);

  • fildes文件描述符
  • 返回值 成功會(huì)返回0,其余均為失敗,需要檢查errno

Tips: 通過(guò) strerror 可以將 errno 轉(zhuǎn)換成可讀的字符串

實(shí)戰(zhàn) C++

一般我們使用open打開(kāi)一個(gè)文件或者目錄后,必須使用 close進(jìn)行釋放,否則會(huì)出現(xiàn)資源泄露.
(這就是很多語(yǔ)言?xún)?nèi)的 Stream類(lèi)打開(kāi)后沒(méi)有關(guān)閉,會(huì)導(dǎo)致各種問(wèn)題的原因之一),所以我們一定要記住Open/Close 總是成對(duì)的使用

#include <unistd.h>
#include <fcntl.h>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cerrno>

int main(int argc, char **argv) {
    constexpr char TargetFile[]{"NewFile.txt"};
    int filefd = ::open(TargetFile, O_RDWR | O_CREAT, 0666);
    if (filefd < 0) {
        printf("open failed ! err :%s\n", strerror(errno));
        return 1;
    }
    printf("open success , fd = %d\n", filefd);
    ::close(filefd);
    return EXIT_SUCCESS;
}

實(shí)戰(zhàn) Golang

相比C++版本調(diào)用的繁瑣,Golang 提供了更加人性化的os.OpenFile 函數(shù),該函數(shù)有兩個(gè)返回值.成功時(shí),返回一個(gè)文件指針,錯(cuò)誤設(shè)置為 nil,失敗時(shí),文件指針為 nil,此時(shí)要讀取錯(cuò)誤信息,并通知用戶.

package main

import (
    "os"
    "fmt"
)

const (
    NewFile = "NewFile.txt"
)

func main() {
    fptr, err := os.OpenFile(NewFile, os.O_RDWR|os.O_CREATE, 0666)
    if err != nil{
        fmt.Println(err.Error())
        return
    }
    fptr.Close()
}

總結(jié)

C++版本的看懂后,Golang 版本是不是也一目了然了,每行發(fā)生了什么事情,心中都有數(shù)了.我們可以做一個(gè)類(lèi)推,Pythonopen,close也一定是這個(gè)原理.這些語(yǔ)言封裝了更好的異常處理,方便程序員去處理 open,close 發(fā)生的問(wèn)題.最重要的一點(diǎn)是 openclose必須成對(duì)的被使用!!!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容