八、Linux下文件IO编程
在linux中对目录和设备的操作都等同于文件的操作,所以提高了效率。每一个文件都有自己的文件描述符,对linux而言,所有对设备和文件的操作都是使用文件描述符来进行的,文件描述符是一个非负的整数。
先试了试这几个函数:
open() read() write() lseek() close()
这几个都是文件IO操作的系统调用用到的主要几个函数。
int open(const char *pathname,int flags,int perms)
int close(int fd);
ssize_t read(int fd,void *buf,size_t count)
ssize_t write(int fd,void *buf,size_t count)
off_t lseek(int fd,off_t offset,int whence)
先编写一个程序把这几个都给用到:
将一个文件里的数据拷贝到另外一个文件里:
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #define OFF_SET 10240 #define READ_SIZE 1024 int main(int argc,char **argv) { int fd_src,fd_des; // 文件描述符 int real_read; unsigned char buf[READ_SIZE]; if(argc != 3) { printf("please enter filename\n"); return 1; } if((fd_src = open(argv[1],O_RDONLY)) < 0) { printf("open file_src error\n"); return 1; } if((fd_des = open(argv[2],O_WRONLY | O_CREAT,777)) < 0) { printf("open file_des error\n"); return 1; } lseek(fd_src,-OFF_SET,SEEK_END); //读取最后10K的数据 memset(buf,0,READ_SIZE); while( (real_read = read(fd_src,buf,READ_SIZE)) > 0) { write(fd_des,buf,real_read); } close(fd_src); close(fd_des); return 0; }
在文件共享的情况下,防止多用户产生竞争的情况,Linux采用的方式是给文件上锁,避免共享的文件产生竞争状态。
文件上锁分为建议性锁和强制性锁。所谓建议性锁就是假定人们都会遵守某些规则去干一件事。例如,人与车看到红灯都会停,而看到绿灯才会继续走,我们可以称红绿等为建议锁。但这只是一种规则而已,你并不防止某些人强闯红灯。而强制性锁是你想闯红灯也闯不了。
(2)fcntl函数格式
用于建立记录锁的fcntl函数格式如表6.6 所示。
表6.6 fcntl函数语法要点所需头文件
#include
#include
#include
函数原型int fcnt1(int fd, int cmd, struct flock *lock)
fd:文件描述符
F_DUPFD:复制文件描述符
F_GETFD:获得fd的close-on-exec标志,若标志未设置,则文件经过exec函数之后仍保持打开状态
F_SETFD:设置close-on-exec标志,该标志以参数arg的FD_CLOEXEC位决定
F_GETFL:得到open设置的标志
函数传入值
cmd
F_SETFL:改变open设置的标志
F_GETFK:根据lock描述,决定是否上文件锁
F_SETFK:设置lock描述的文件锁
F_SETLKW:这是F_SETLK的阻塞版本(命令名中的W表示等待(wait))。
如果存在其他锁,则调用进程睡眠;如果捕捉到信号则睡眠中断
F_GETOWN:检索将收到SIGIO和SIGURG信号的进程号或进程组号
F_SETOWN:设置进程号或进程组号
函数返回值
Lock:结构为flock,设置记录锁的具体状态,后面会详细说明
成功:0
-1:出错
这里,lock的结构如下所示:
Struct flock{
short l_type;
off_t l_start;
short l_whence;
off_t l_len;
pid_t l_pid;
}
lock结构中每个变量的取值含义如表6.7 所示。
表6.7 lock结构变量取值
F_RDLCK:读取锁(共享锁)
l_type F_WRLCK:写入锁(排斥锁)
F_UNLCK:解锁
l_stat 相对位移量(字节)
SEEK_SET:当前位置为文件的开头,新位置为偏移量的大小
SEEK_CUR:当前位置为文件指针的位置,新位置为当前位置加上偏移量
l_whence:相对位移量的起点(同lseek 的whence)。
SEEK_END:当前位置为文件的结尾,新位置为文件的大小加上偏移量的大小
l_len 加锁区域的长度
小技巧:
为加锁整个文件,通常的方法是将l_start 说明为0,l_whence 说明为SEEK_SET,l_len 说明为0。