C3 文件IO:APUE笔记

C3:文件IO

1 引言

  本章描述的函数被成为不带缓冲的IO,涉及5个函数,分别时

  open、read、write、lseek、close。

2 文件描述符

  文件描述符为非负整数,取值范围为0 ~ OPEN_MAX - 1,调用open、create返回参数路径的文件描述符,可以作为传递给read、write。

  可使用shell命令查询系统对OPEN_MAX定义,grep -rn --col OPEN_MAX /usr/include

  linux三个特殊的文件描述符:

  0:标准读,STDIN_FILENO,该常亮在unistd.h中定义

  1:标准写,STDOUT_FILENO

  2:标准错误,STDERR_FILENO

3 函数open与openat

  该方法可以打开或者创建一个文件,头文件 fctnl.h

 1 /* Open FILE and return a new file descriptor for it, or -1 on error.
 2    OFLAG determines the type of access used.  If O_CREAT or O_TMPFILE is set
 3    in OFLAG, the third argument is taken as a `mode_t', the mode of the
 4    created file.
 5 
 6    This function is a cancellation point and therefore not marked with
 7    __THROW.  */
 8 #ifndef __USE_FILE_OFFSET64
 9 extern int open (const char *__file, int __oflag, ...) __nonnull ((1));
10 #else
11 # ifdef __REDIRECT
12 extern int __REDIRECT (open, (const char *__file, int __oflag, ...), open64)
13      __nonnull ((1));
14 # else
15 #  define open open64
16 # endif
17 #endif
18 
19 #ifdef __USE_ATFILE
20 /* Similar to `open' but a relative path name is interpreted relative to
21    the directory for which FD is a descriptor.
22 
23    NOTE: some other `openat' implementation support additional functionality
24    through this interface, especially using the O_XATTR flag.  This is not
25    yet supported here.
26 
27    This function is a cancellation point and therefore not marked with
28    __THROW.  */
29 # ifndef __USE_FILE_OFFSET64
30 extern int openat (int __fd, const char *__file, int __oflag, ...)
31      __nonnull ((2));
32 # else
33 #  ifdef __REDIRECT
34 extern int __REDIRECT (openat, (int __fd, const char *__file, int __oflag,
35                 ...), openat64) __nonnull ((2));
36 #  else
37 #   define openat openat64
38 #  endif
39 # endif
40 # ifdef __USE_LARGEFILE64
41 extern int openat64 (int __fd, const char *__file, int __oflag, ...)
42      __nonnull ((2));
43 # endif
44 #endif
View Code

   各参数释义如下:

  path:打开或者创建文件的名字。

  oflag:用于指定操作类型,如下:

 

常量  释义
O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 读写打开
O_EXEC 只执行打开
O_SEARCH 只搜索打开(仅应用于目录)
O_APPEND 写文件时,追加到文件末尾
O_CLOEXEC 把FD_CLOEXEC设置为文件描述符标志
O_CREATE 创建文件,参数mode用于指定访问权限
O_DIRECTORY 如果path不是目录,则出错
O_EXCL 测试文件是否存在。不能与O_CREAT公用,否则会报错
O_NOCTTY 如果path是终端设备,则不降该设计分配为此进场的控制终端
O_NOFOLLOW 如果path是符号链接,则出错
O_NONBLOCK 如果path时FIFO、块特殊文件、字符特殊文件,则将本次打开操作及后续IO操作设置为非阻塞
O_SYNC 每次write等待IO操作完成
O_TRUNK 文件存在,且为写打开(包括只写、读写),则将文件长度截断为0。即写指针移位到0
O_TTY_INIT  
O_DSYNC write等待IO操作完成,如果写操作不影响读取刚写入的数据,则不需要等待文件属性被更新
O_RSYNC read操作等待,直至所有对文件同一部分挂起的写操作都完成

  

  openat与open区别如下:

  •   如果openat的path是绝对文件名,则fd参数被忽略,openat等同于open
  •   path参数是相对文件名,fd指定了相对路径名的文件描述符,fd参数通过打开相对路径名所在的目录获取文件。
  •   path指定相对路径名,fd参数具有特殊值AT_FDCWD,则路径名表示为当前目录获取,在操作上与open函数类似。

4 函数creat

  创建一个新文件,头文件fcntl.h

 1 /* Create and open FILE, with mode MODE.  This takes an `int' MODE
 2    argument because that is what `mode_t' will be widened to.
 3 
 4    This function is a cancellation point and therefore not marked with
 5    __THROW.  */
 6 #ifndef __USE_FILE_OFFSET64
 7 extern int creat (const char *__file, mode_t __mode) __nonnull ((1));
 8 #else
 9 # ifdef __REDIRECT
10 extern int __REDIRECT (creat, (const char *__file, mode_t __mode),
11                creat64) __nonnull ((1));
12 # else
13 #  define creat creat64
14 # endif
15 #endif
16 #ifdef __USE_LARGEFILE64
17 extern int creat64 (const char *__file, mode_t __mode) __nonnull ((1));
18 #endif
View Code

  等价于open(path, O_WRONLY | O_CREAT | O_TRUNK, mode)

5 函数close

  关闭一个打开的文件,头文件 unistd.h

1 /* Close the file descriptor FD.
2 
3    This function is a cancellation point and therefore not marked with
4    __THROW.  */
5 extern int close (int __fd);
View Code

  关闭一个文件会释放该进程加在文件上的所以记录锁。

  当一个进场终止时,内核会自动关闭它打开的所有文件,很多程序利用这一功能而不显示调用close关闭文件。

6 函数lseek

  操作文件偏移量,头文件 unistd.h

 1 /* Move FD's file position to OFFSET bytes from the
 2    beginning of the file (if WHENCE is SEEK_SET),
 3    the current position (if WHENCE is SEEK_CUR),
 4    or the end of the file (if WHENCE is SEEK_END).
 5    Return the new file position.  */
 6 #ifndef __USE_FILE_OFFSET64
 7 extern __off_t lseek (int __fd, __off_t __offset, int __whence) __THROW;
 8 #else
 9 # ifdef __REDIRECT_NTH
10 extern __off64_t __REDIRECT_NTH (lseek,
11                  (int __fd, __off64_t __offset, int __whence),
12                  lseek64);
13 # else
14 #  define lseek lseek64
15 # endif
16 #endif
View Code

  参数whence释义如下:

  取值为SEEK_SET,则将文件偏移量设置为距离文件开始处offset个字节

  取值为SEECK_CUR,则将文件偏移量设置为当前值加上offset,offset可正可负

  取值为SEEK_END,则将文件偏移量设置为文件长度加上offset,offset可正可负

猜你喜欢

转载自www.cnblogs.com/hgwang/p/9602584.html
C3