Linux 之 POSIX 文件 I/O 操作函数

在这里插入图片描述

(1)文件描述符与文件流转换操作

/*成功返回文件描述符,失败返回-1*/
int fileno(FILE* stream);

/*成功返回文件流,失败返回NULL*/
FILE* fdopen(int fd,char* mode);

(2)修改文件描述符的特殊属性

int fcntl(int fd,int cmd,...);

第一个参数为文件描述符,第二个参数cmd为响应操作,失败返回-1,常用命令如下:

#define  F_DUPFD       0   /*复制文件描述符,ag:fcntl(fd,F_DUPFD)*/
#define  F_GETFD       1   /*获取文件描述符标志*/
#define  F_SETFD       2   /*设置文件描述符标志*/
#define  F_GETFL       3   /*获取文件状态,ag:fcntl(fd,F_GETFL,0)*/
#define  F_SETFL       4   /*设置文件状态*/

(3)同步内核缓冲区sync、fsync、fdatasync

#include <unistd.h>
void sync(void);
int fsync(int fd);
int fdatasync(int fd);

函数sync()始终成功,但只是将修改过的块的缓存排入写队列,并不等待 实际I/O操作结束。系统守护进程会周期性的(一般30s)会调用一次sync()函数,从而保证系统定期刷新内核缓存。
函数fsync()函数则等待实际I/O结束才返回,从而确保修改过的块立即写到硬盘上,成功返回0,否则返回-1。
函数fdatasync()只是更新硬盘文件内容,如果没有必要,并不更新元数据,即文件的属性(长度、上次修改时间等),成功返回0,否则返回-1。

(4)锁定/解锁文件

// from /usr/include/sys/file.h
int flock(int fd,int operation);

函数的第一个参数为欲锁定/解锁的文件描述符,第二个参数为操作命令:

// from /usr/include/sys/file.h
#define  LOCK_SH  1 /* 共享锁:多个进程可同时对一个文件进行共享读操作,但不能排他写锁定*/
#define  LOCK_EX  2 /* 排他锁:任意两个进程不能同时操作同一个文件 */
#define  LOCK_UN  8 /* 解锁:解除文件锁定状态 */
#define  LOC_NB   4 /* 无法建立锁时,立即返回 */

(5)映射文件到内存

#include <sys/mman.h>
void* mmap(void* start,size_t length,int prot,int flags,int fd,off_t offset);

该函数将进程的虚拟地址空间与文件fd建立映射关系,这样进程就可以像访问内存一样,访问文件了,各参数说明如下:
start: 映射内存的首地址,必须为内存页大小(PAGE_SIZE)的整数倍,当然也可以置为NULL,表示由系统分配。

length:映射的文件长度

prot: 映射的内存权限,但不得与文件的打开权限冲突,该参数有以下选项的组合:
PORT_READ: 允许读该内存
PORT_WRITE: 允许写该内存
PORT_EXEC: 允许执行该内存段
PORT_NONE: 该内存段不能被访问

flags:控制程序对该内存段修改时,造成的影响范围,常用的选项如下:
MAP_PRIVATE: 内存是私有的,对他的修改只在局部范围内有效,其他进程不可见。
MAP_SHARED: 内存是共享的,某进程对该段内存空间的更新对其他进程是可见的

fd: 映射文件的文件描述符

offset:映射内容在该文件的起始偏移位置

此外,一般mmap()函数常与munmap()、msync()结合一起使用,函数声明如下:

int munmap(void* start,size_t length);   /* 解除映射 */
int msync(const void* start,length,int flags);/* 立即将内存修改内容写入文件 */

其中start为内存开始位置,length为长度,flags选项如下:
MS_ASYNC: 请内核尽快将修改写入文件
MS_SYNC : 在此函数返回前,将修改写入到文件
MS_INVALIDATE:内核自行决定是否立即写入

(6)截短文件

#include <unistd.h>
int ftruncate(int fd, off_t length);

将文件大小改变为参数length指定的大小,如果原来的文件大小比参数length大,则超过的部分会被删除,如果原来的文件大小比参数length小,则文件将被扩展,与lseek系统调用类似,文件的扩展部分将以0填充。如果文件的大小被改变了,则文件的st_time 和st_ctime将会更新。

(7)文件属性获取

// from /usr/include/sys/stat.h
int stat(const char* filename,struct stat* buf);   //普通文件(传入绝对路径或相对路径)
int fstat(int fd,struct stat* buf);                //普通文件(传入已打开的fd)
int lstat(const char* filename,struct stat* buf);  //符号链接文件

不同情形选择不同函数,作用都是获取指定文件的属性,并保存在结构体buf中。其中结构体struct stat定义如下:

struct stat
{
	unsigned short   st_dev;              //设备号
	unsigned short   _pad1;              
	unsigned long    st_ino;              //文件inode值
	unsigned short   st_mode;             //文件类型及权限
	unsigned short   st_nlink;            //硬件连接数
	unsigned short   st_uid;              //用户ID
	unsigned short   st_gid;              //用户组ID
	unsigned short   st_rdev;             //设备号
	unsigned short   _pad2;
	unsigned long    st_size;             //文件大小
	unsigned long    st_biksize;          //数据块大小
	unsigned long    st_blocks;           //数据块数量
	unsigned long    st_atime;            //最后一次访问时间
	unsigned long    _unused1;
	unsigned long    st_mtime;            //最后一次修改时间
	unsigned long    _unused2;
	unsigned long    st_ctime;            //最后一次改变属性时间
	unsigned long    _unused3;
	unsigned long    _unused4;
	unsigned long    _unused5;
}

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chiang木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值