赞
踩
标准输入、标准输出、标准错误
- 在UNIX系统shell中把:
- 文件描述符0:表示标准输入
- 文件描述符1:表示标准输出
- 文件描述符2:表示标准错误
- 在头文件中<unistd.h>种用常量表示了上面的描述符值:
- STDIN_FILENO:0
- STDOUT_FILENO:1
- STDERR_FILENO:2
- #include<fcntl.h>
- int open(const char *pathname, int oflag, .../*, mode_t mode*/);
- int openat(int fd, const char *pathname, int oflag, .../*, mode_t mode*/);
-
- //返回值:若成功为文件描述符,若出错为-1
openat()函数的fd参数
- ①如果path参数指定的是绝对路径名,则fd参数会被忽略。openat函数相当于open
- ②path参数指定的是相对路径名,fd参数指出了相对路径名在文件系统中的开始地址。fd参数是通过打开相对路径名所在的目录来获取
- ③path参数指定了相对路径名,fd参数具有特殊值AT_FDCWD。这种情况下,路径名在当前工作目录中获取。openat()在操作上与open()函数类似
pathname参数
- 表示打开/创建的文件的名称
oflag参数
- 下面的选项在头文件<fcntl.h>中定义
- 下面这5个选项必须指定一个,并且只能指定一个:
O_RDONLY 只读打开 O_WRONLY 只写打开 O_RDWR 读、写打开 O_EXEC 只执行打开 O_SEARCH 只搜索打开(应用于目录)。
目的在于目录打开时验证它的搜索权限。对目录的文件描述符的后续操作就不需要再次检查该目录的搜索权限(目前还不支持这个选项)
- 下面的选项是可选的:
O_APPEND 每次写时都追加到文件的尾端 O_CLOEXEC 把FD_CLOEXEC常量设置为文件描述符标志 O_CREAT 若此文件不存在则创建它。使用此选择项时,需同时说明第三个参数mode,mode代表该新文件的权限 O_DIRECTORY 如果path引用的不是目录,则出错 O_EXCL 如果同时指定了O_ CREAT,而文件已经存在,则出错。这可测试一个文件是 否存在,如果不存在则创建此文件。使得测试和创建成为一个原子操作 O_NOCTTY 如果pathname引用的是终端设备,则不将该设备分配作为此进程的控制终端 O_NOFOLLOW 如果pathname引用的是一个符号链接,则出错 O_NONBLOCK 如果pathname指的是一个FIFO、一个块特殊文件或一个字符特殊文件, 则此选择项为此文件的本次打开操作和后续的I/O操作设置非阻塞方式
O_SYNC 使每次write都等到物理I/O操作完成(直至数据已写到磁盘上再返回),包括由该write操作引起的文件属性更新所需的I/O。数据库系统需要使用这个参数
通常write只将数据排入队列就返回了,而实际的写磁盘操作则可能在以后的某个时刻进行。如果使用O_SYNC,则直至数据已写到磁盘上write才返回,以免系统异常时产生数据丢失
O_SYNC标志会增加系统时间和时钟时间
O_TRUNC 如果此文件存在,而且为只读或只写成功打开,则将其长度截短为0 O_TTY_INIT 如果打开一个还未打开的终端设备,设置非标准termios参数值,使其符合Single UNIX Specification
- 下面的选项也是可选的。它们是Single UNIX Specification(以及POSIX.1)中同步输入和输出选项的一部分
O_DSYNC 使每次write要等待物理I/O操作完成,但是如果该写操作并不影响读取刚写入的数据,则不需要等待文件属性被更新
O_RSYNC 使每一个以文件描述符作为参数进行的read操作等待,直至所有对文件同一部分挂起的写操作都完成
mode参数如下
文件名限制和路径名截断
- NAME_MAX:表示文件名的最大字节数
- 如果NAME_MAX是14,而我们却创建了一个文件名包含15个字符的新文件,那么此时会发生什么呢?
- 早期的System V版本(如SVR2)允许这种使用方法,但总是将文件名截断为14个字符,而且不给出任何信息
- BSD类的系统则返回出错状态,并将errno设置为ENAMETOOLONG
- _POSIX_NO_TRUNC:
- 表示当文件名长度超过NAME_MAX时,决定要决定截断过程的文件名或路径名,还是返回一个错误
- 如果_POSIX_NO_TRUNC有效,则超过NAME_MAX时,出错返回将errno设置为ENAMETOOLONG
- #include<fcntl.h>
- int creat(const char* path, mode_t mode);
-
- //参数:1.文件路径名 2.创建文件的权限
- //返回值:成功返回只写打开的文件描述符;失败的返回-1
open(pathname, O_WRONL|YO_CREAT|O_TRUNC, mode);
该函数已经淘汰了
- 在早期的UNIX系统中,open()的第二个参数只能是0、1、2,因此无法创建一个新文件,所以才使用creat来创建文件
- 现在open()函数提供了O_CREAT和O_TRUNC,因此这个函数就淘汰了
open(pathname, O_RDWR|YO_CREAT|O_TRUNC, mode);
- #include<unistd.h>
- int close(int fd);
-
- //返回值:成功返回0;出错,返回-1
- //参数:文件描述符
- #include <unistd.h>
- off_t lseek(int fd, off_t offset, int whence);
-
- //返回:若成功为新的文件位移(长整型),若出错为-1
- //参数2:相对于参数3的偏移量(正数表示正向偏移,负数表示负向偏移)。参数3:设定从文件的哪里开始偏移
参数3的取值
- SEEK_SET: 文件开头(0)
- SEEK_CUR: 当前位置(1)
- SEEK_END: 文件结尾(2)
- 如果文件描述符引用的是一个管道或FIFO,则l seek返回-1,并将errno设置为EPIPE
- 通常,文件的当前位移量应当是一个非负整数,但是,某些设备也可能允许负的位移量。 但对于普通文件,则其位移量必须是非负值。因为位移量可能是负值,所以在比较lseek的返回 值时应当谨慎,不要测试它是否小于0,而要测试它是否等于-1
- 注意:文件位移量可以大于文件的当前长度,在这种情况下,对该文件的下一次写将延长该文件, 并在文件中构成一个空洞,这一点是允许的。位于文件中但没有写过的字节都被设为0
- 这些0还存储在文件中,但是查看时不会显示。使用vim编辑时会显示
- 文件中的空洞并不要求在磁盘上占用存储区。具体处理与文件系统的实现有关。但是新写入的数据需要磁盘数量存储
#include <fcntl.h> #include<stdlib.h> #include<stdli.h> char buf1[] = "abcdefghij"; char buf2[] = "ABCDEFGHIJ"; int main(void) { int fd; if ((fd = creat("file.hole", 0644)) < 0) perror("creat error"); if (write(fd, buf1, 10) != 10) perror("buf1 write error"); /* offset now = 10 */ if (lseek(fd,30, SEEK_SET) == -1) perror("lseek error"); /* offset now = 30*/ if (write(fd, buf2, 10) != 10) perror("buf2 write error"); /* offset now = 40*/ exit(0); }
- 查看文件的内容,以及文件存储在的内存
![]()
- #include <unistd.h>
- ssize_t read(int fd, void *buf, size_t nbytes);
有多种情况可使实际读到的字节数少于要求读字节数
- 读普通文件时,在读到要求字节数之前已到达了文件尾端。例如,若在到达文件尾端之 前还有3 0个字节,而要求读1 0 0个字节,则read返回3 0,下一次再调用read时,它将返回0 (文件尾端)
- 当从终端设备读时,通常一次最多读一行(“终端I/O”文章会介绍如何改变这一点)
- 当从网络读时,网络中的缓冲机构可能造成返回值小于所要求读的字节数
- 某些面向记录的设备,例如磁带,一次最多返回一个记录
- 当一信号造成中断,而已经读了部分数据量时(详情参阅:https://blog.csdn.net/qq_41453285/article/details/89216990)
- #include <unistd.h>
- ssize_t write(int fd, const void *buf, size_t nbytes);
- #include<stdio.h>
- #include<stdlib.h>
- #include<unistd.h>
- #define BUFFSIZE 1024
- int main()
- {
- int n;
- char buff[BUFFSIZE];
- while((n=read(STDIN_FILENO,buff,BUFFSIZE))>0)
- if(write(STDOUT_FILENO,buff,n)!=n)
- perror("write");
- if(n<0)
- perror("read");
- exit(0);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。