美文网首页APUE 学习之旅
[APUE] 文件 I/O 之 Open/Close

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

作者: 疯狂的攻城狮 | 来源:发表于2018-01-04 14:00 被阅读0次

    前言

    上一篇文章,主要讲了文件描述符的基本知识.这篇,我将会结合代码,对上一节的 open,close函数进行详细的讲解.

    代码 Git 地址 SuzhenProjects/ApueProject

    常用函数复习

    • open 打开或者创建一个用来读/写的文件
    • read 读取用户指定的 Input
    • write 写入到指定的 Output
    • lseek 重新定位读写游标的位置
    • close 删除(关闭)一个文件描述符

    Tips: 通过 man 2 <Command> 可以查询你系统的这些 API 档案

    Open 函数 int open(const char *path, int oflag, ...);

    • path 文件的路径,如果文件不存在,则返回错误
    • oflag 打开文件/目录,所使用的用户自定义选项
      • O_RDONLY 只读
      • O_WRONLY 只写
      • O_RDWR 读/写
      • O_NONBLOCK 打开文件时/读取数据时,不要阻塞调用
      • O_APPEND 追加模式,write的内容被追加到文档的末尾
      • O_CREAT 如果文件不存在,open会创建文件
      • O_TRUNC 截断文件,使文件长度为0
      • O_EXCL 存在O_CREAT模式时,如果文件存在,会返回错误
      • O_SHLOCK 自动获取 flock 的共享锁
      • O_EXLOCK 自动获取 flock的独占锁
      • O_NOFOLLOW 打开文件的链接时, 会失败
      • O_SYMLINK 运行打开文件的链接
      • O_EVTONLY 用来监视文件是否有改动
      • O_CLOEXEC 标记为close-on-exec
    • 扩展参数
      • 可以传入文件的权限标志 如 0755,0666
    • 返回值 成功会返回一个正整数,其余均为失败,需要检查errno

    Close 函数 int close(int fildes);

    • fildes文件描述符
    • 返回值 成功会返回0,其余均为失败,需要检查errno

    Tips: 通过 strerror 可以将 errno 转换成可读的字符串

    实战 C++

    一般我们使用open打开一个文件或者目录后,必须使用 close进行释放,否则会出现资源泄露.
    (这就是很多语言内的 Stream类打开后没有关闭,会导致各种问题的原因之一),所以我们一定要记住Open/Close 总是成对的使用

    #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;
    }
    

    实战 Golang

    相比C++版本调用的繁琐,Golang 提供了更加人性化的os.OpenFile 函数,该函数有两个返回值.成功时,返回一个文件指针,错误设置为 nil,失败时,文件指针为 nil,此时要读取错误信息,并通知用户.

    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()
    }
    
    

    总结

    C++版本的看懂后,Golang 版本是不是也一目了然了,每行发生了什么事情,心中都有数了.我们可以做一个类推,Pythonopen,close也一定是这个原理.这些语言封装了更好的异常处理,方便程序员去处理 open,close 发生的问题.最重要的一点是 openclose必须成对的被使用!!!

    相关文章

      网友评论

        本文标题:[APUE] 文件 I/O 之 Open/Close

        本文链接:https://www.haomeiwen.com/subject/jbhrnxtx.html