Linux下的文件I/O有
两种方式:
系统调用和
标准c语言的I/O.
1.不带文件缓冲区的I/O
1.1文件描述符
所有的文件操作都要以文件描述符来引用,其是一个非负整数.在unistd.h中定义.范围是:是0-OPEN_MAX.以前是19,现在是63.对于一个进程而言
1.2基本函数
open函数:
#include <sys/type.h> #include <sys/stat.h> #include <fcntl.h> //定义文件夹标志
int open(const char *pathName, int flag, mode_t *mode); //ok:>0 no:-1
|
mode只有在创建文件时使用
flag:
O_RDONLY >>>只读
O_WRONLY >>>只写
O_RDWR >>>读写
>>>以上三个只能用一个,不能组合.下面的是可以和它们以|来组合使用的标志
O_APPEND >>>追加
O_CREAT >>>不存在则创建,要加第三个参数mode,即文件权限
O_EXCL >>>
O_TRUNC
O_NOCTTY
O_NONBLOCK >>>非阻塞
O_SYNC >>>
I/O同步,每次write都等到物理I/O操作完成如:
open(pathname, O_RDWR|O_CREAT|O_TRUNC, mode);
close函数:
#include <unistd.h>
int close(int filedes); //ok:0 no:-1
|
lseek函数:
#include <sys/types.h> #include <unistd.h>
off_t lseek(int filedes, off_t offset, int whence); //ok:新的指针位置 no:-1
|
offset:是一个整数,可以是正或负值,其作用与后面的wherce参数有关
whence:
SEEK_SET >>>设置指针到offset-0,位移也可能是负值,所以判断返回值时一定要判断是否等于-1
SEEK_CUR >>>设置指针到offset-当前位置
SEEK_END >>>设置指针到offset-末尾,位移可以大于当前文件长度,空洞填0
如:
off_t currpos;
currpos=lseek(fd, 0, SEEK_CUR);
read函数:
#include <unistd.h> ssize_t read(int filedes, void *buff, size_t nbytes); //ok:读取的字节数,到达末尾时返回0 no:-1
|
读取成功后,
指针会后移实际读取的字节数write函数:
#include <unistd.h>
ssize_t write(int filedes, const void *buff, size_t nbytes); //ok:实际写入的字节数 no:-1
|
1.3文件
共享1.3.1
原子操作
多个操作,但是
不可分割地执行了,要么执行完成,要么不执行.
防止多进程操作时出现的不同步.1.3.2相关函数
dup与dup2函数:
#include <unistd.h>
int dup(int filedes); //返回一个新的文件描述符,为未用的最小文件描述符
int dup2(int filedes1, int filedes2); //返回filedes2,如果filedes2已经存在先关闭,再把filedes1連接的文件描述符的連接傳遞給filedes2,使得文件于filed1相連
|
fcntl函数:
#include <sys/types.h> #include <unistd.h> #include <fcntl.h>
//在运行时对文件描述符的标志进行修改 int fcntl(int filedes, int cmd, [int arg]); //返回值与cmd有关 no:-1
|
cmd:
F_DUPFD >>>复制文件描述符,新的文件描述符是大于等于arg的最小未分配的文件描述符
F_GETFD >>>将本文件描述符的标志以整数形式返回
F_SETFD >>>设置当前文件描述符标志为arg
F_GETFL >>>获取filedes的文件描述符标志返回之,要先用O_ACCMODE取得存取方式位然后再作比较
F_SETFL >>>更改文件描述符标志.可以更改的标志:O_APPEND,O_NONBLOCK,O_SYNC和O_ASYN C
F_GETOWN和F_SETOWN >>>取得或设置接收SIGIO和SIGURG进程ID可组ID
修改文件描述符标志的函数实例:
#include <fcntl.h>
void set_fl(int fd, int flags){ int val; if((val=fcntl(fd, F_GETFL, 0))<0) err_sys("fcntl F_GETFL error"); val |= flags; //相当于追加标志设置 if(fcntl(fd, F_SETFL, val)<0) err_sys("fcntl F_SETFL error"); }
|
获取当前文件描述符标志后进行比较:
int val, accmode; val=fcntl(fd, F_GETFL, 0); accmode=val & O_ACCMODE; // 先用O_ACCMODE取得存取方式位然后再作比较 if(accmode==O_RDONLY)
|