[APUE] 文件 I/O 之 Open/Close
2018-01-04 本文已影响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
版本是不是也一目了然了,每行发生了什么事情,心中都有数了.我们可以做一个类推,Python
的open
,close
也一定是这个原理.这些语言封装了更好的异常处理,方便程序员去处理 open
,close
发生的问题.最重要的一点是 open
和close
必须成对的被使用!!!