文件常用操作IO:open close read write
1.打开文件 open
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
//两个参数的open用于 打开已存在的文件
int open(const char*pathname,int flags);
//三个参数的open用于 打开不存在的文件 mode就是文件在磁盘上的权限7
int open(const char*pathname,int flags,mode_t mode);
功能:
打开文件,如果文件不存在则可以选择创建。
参数:
pathname:文件的路径及文件名
flags:打开文件的行为标志,必选项 O_RDONLY, O_WRONLY, O_RDWR
mode:这个参数,只有在文件不存在时有效,指新建文件时指定文件的磁盘权限
返回值:
成功:成功返回打开的文件描述符
失败:-1
(1) flags 文件的操作权限
O_RDONLY 以只读的方式打开
O_WRONLY 以只写的方式打开
O_RDWR 以可读、可写的方式打开O_CREAT 文件不存在则创建文件,使用此选项时需使用mode说明文件的权限
O_EXCL 如果同时指定了O_CREAT,且文件已经存在,则出错
O_TRUNC 如果文件存在,则清空文件内容
O_APPEND 写文件时,数据添加到文件末尾
O_NONBLOCK 对于设备文件, 以O_NONBLOCK方式打开可以做非阻塞I/O
mode文件在磁盘的用户权限磁盘文件的用户权限分类:所有拥有者权限(u)、同组用户权限(g)、其他用户权限(o)
(2) mode文件在磁盘的用户权限
磁盘文件的用户权限分类:所有拥有者权限(u)、同组用户权限(g)、其他用户权限(o)
任何权限都分为:读(4)、写(2)、执行(1) 这3个数值可以组合
7--->可读可写可执行 6--->可读可写 5--->可读可执行 4--->只读3--->可写可执行 2--->只写 1--->可执行
mode的权限表示0xxx 每一个x都是(4,2,1)的组合
0777 所有者、同组用户、其他用户都是可读可写可执行
0666 所有者、同组用户、其他用户都是可读可写
0651 所有者可读可写 、同组用户可读可执行、其他用户可执行
(3) mode的系统掩码
查看掩码:umask
umask -S:查看各组用户的默认操作权限
文件的最终权限=给定的权限 & ~umask
umask mode:设置掩码,mode为八进制数
2、close关闭文件描述符
#include<unistd.h>
int close(int fd);
功能:
关闭已打开的文件
参数:
fd : 文件描述符,open()的返回值
返回值:
成功:0
失败: -1, 并设置errno
注意:close工作步骤,先将文件描述符的数量-1,当文件描述符的数量变为0的时候 ,系统回收文件描述符所占的内核空间。
3、向文件写数据write
#include<unistd.h>
ssize_t write(int fd,const void*buf,size_t count);
功能:
把指定数目的数据写到文件(fd)
参数:
fd : 文件描述符
buf : 数据首地址
count : 写入数据的长度(字节)
返回值:
成功:实际写入数据的字节个数
失败: - 1
4、read读取文件数据
#include<unistd.h>
ssize_t read(int fd,void*buf,size_t count);
功能:
把指定数目的数据读到内存(缓冲区)
参数:
fd : 文件描述符
buf : 内存首地址count : 读取的字节个数
返回值:
成功:实际读取到的字节个数
读完文件数据返回0
失败: - 1
5、 文件的阻塞特性
阻塞和非阻塞 针对的是文件描述符 而不是read write函数
文件描述符 默认 为阻塞的。
1、通过open函数 在打开文件的时候 设置文件描述符为非阻塞。
O_NONBLOCK
2、通过fcntl设置文件的阻塞特性
#include<unistd.h>
#include<fcntl.h>
int fcntl(int fd,int cmd, .../*arg*/);
功能:
改变已打开的文件性质,fcntl针对描述符提供控制。
参数:
fd:操作的文件描述符
cmd:操作方式arg:针对cmd的值,fcntl能够接受第三个参数int arg。
返回值:
成功:返回某个其他值
失败:-1
fcntl函数有5种功能:
1) 复制一个现有的描述符(cmd=F_DUPFD)
2) 获得/设置文件描述符标记(cmd=FGETFD 或 FSETFD)
3) 获得/设置文件状态标记(cmd=FGETFL 或 FSETFL)
4) 获得/设置异步 I/O 所有权(cmd=FGETOWN 或 FSETOWN)
5) 获得/设置记录锁(cmd=FGETLK, FSETLK 或 F_SETLKW)
6、 获取文件的状态信息
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
int stat(const char*path,struct stat*buf);
int lstat(const char*pathname,struct stat*buf); //不穿透
功能:
获取文件状态信息
stat 和 lstat 的区别:
当文件是一个符号链接时,lstat 返回的是该符号链接本身的信息;
而 stat 返回的是该链接指向的文件的信息。
参数:
path:文件名
buf:保存文件信息的结构体
返回值:
成功: 0失败: -1
struct stat 结构体说明:
struct stat{
dev_t st_dev; //文件的设备编号
ino_t st_ino; //节点
mode_t st_mode; //文件的类型和存取的权限
nlink_t st_nlink; //连到该文件的硬连接数目,刚建立的文件值
uid_t st_uid; //用户ID
gid_t st_gid; //组ID
dev_t st_rdev; //(设备类型)若此文件为设备文件,则为其设
off_t st_size; //文件字节数(文件大小)
blksize_t st_blksize; //块大小(文件系统的I/O 缓冲区大小)
blkcnt_t st_blocks; //块数
time_t st_atime; //最后一次访问时间
time_t st_mtime; //最后一次修改时间
time_t st_ctime; //最后一次改变时间(指属性)
};
st_mode(16位整数)参数说明 :
![](https://img.haomeiwen.com/i1607463/586b53501d36e492.png)
![](https://img.haomeiwen.com/i1607463/f98bbaa9af1ca35c.png)
7、重新定位读/写文件偏移量lseek
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
功能:
改变文件的当前位置
参数:
fd:文件描述符
offset:文件偏移量
whence:文件偏移相对位置
SEEK_SET:将文件指针偏移到传入字节数处(文件头开始偏移)
SEEK_CUR:将文件指针偏移到当前位置加上传入字节数处;((当前位置开始偏移)
SEEK_END:将文件指针偏移到文件末尾加上传入字节数处(作为拓展作用,必须再执行一次写操作)
返回值:成功:返回文件新的偏移量(成功)
8、文件目录操作
1、得到文件目录的句柄
#include<sys/types.h>
#include<dirent.h>
DIR*opendir(const char*name);
功能:
打开一个目录
参数:
name:目录名
返回值:
成功:返回指向该目录结构体指针
失败:NULL
2、读取目录
#include<dirent.h>
struct dirent *readdir(DIR *dirp);
功能:
读取目录 调用一次只能读取一个文件
参数:
dirp:opendir的返回值
返回值:
成功:目录结构体指针
失败:NULL
struct dirent{
ino_t d_ino; // 此目录进入点的 inode
off_t d_off; // 目录文件开头至此目录进入点的位移
signed short int d_reclen; // d_name 的长度, 不包含 NULL 字符
unsigned char d_type; // d_type 所指的文件类型
char d_name[256]; // 文件名
};
d_type相关数据:
![](https://img.haomeiwen.com/i1607463/9d2421aff20ae8c3.png)
3、关闭目录
#include<sys/types.h>
#include<dirent.h>
int closedir(DIR *dirp);
功能:
关闭目录
参数:
dirp:opendir返回的指针
返回值:
成功:0
失败:-1
网友评论