(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
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
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
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;
}