不带缓存的文件I/O操作主要有5个函数open、read、write、lseek和close。这几个不带缓存的操作是指每一个函数都只调用系统中的一个函数。这些函数不是ANSIC组成部分,但属于POSIX的组成部分。
1.open函数(返回的文件描述符一定是最小的且没有被用过的数值)
open 函数用于打开和创建文件。
所需都文件
#include
#include
#include
函数原型 int open(const char *pathname, int flags, ... /* mode_t mode */);
返回值:成功则返回文件描述符,否则返回 -1
pathname 是待打开/创建文件的路径名(如 C:/cpp/a.cpp);
第三个参数 (...)仅当创建新文件时才使用,用于指定文件的访问权限位(access permission bits)。
flags 用于指定文件的打开/创建模式,这个参数可由以下常量(定义于 fcntl.h)通过逻辑或(|)构成。
O_RDONLY 只读模式
O_WRONLY 只写模式
O_RDWR 读写模式
打开/创建文件时,用且只能用三个常量中的一个。以下常量是选用的:
O_APPEND 每次写操作都写入文件的末尾
O_CREAT 如果指定文件不存在,则创建这个文件
O_EXCL 如果要创建的文件已存在,则返回 -1,并且修改 errno 的值,用于测试文件是否存在
O_TRUNC 如果文件存在,并且以只写/读写方式打开,则清空文件全部内容
O_NOCTTY 如果路径名指向终端设备,不要把这个设备用作控制终端。
O_NONBLOCK 如果路径名指向 FIFO/块文件/字符文件,则把文件的打开和后继 I/O
设置为非阻塞模式(nonblocking mode)
以下三个常量同样是选用的,它们用于同步输入输出
O_DSYNC 等待物理 I/O 结束后再 write。在不影响读取新写入的数据的前提下,不等待文件属性更新。
O_RSYNC read 等待所有写入同一区域的写操作完成后再进行
O_SYNC 等待物理 I/O 结束后再 write,包括更新文件属性的 I/O
(2)访问权限位的取值可以取一下值:文件权限应该为(mode-umaks)。
S_IRWXU00700 权限,代表该文件所有者具有可读、可写及可执行的权限。
S_IRUSR 或S_IREAD,00400权限,代表该文件所有者具有可读取的权限。
S_IWUSR 或S_IWRITE,00200 权限,代表该文件所有者具有可写入的权限。
S_IXUSR 或S_IEXEC,00100 权限,代表该文件所有者具有可执行的权限。
S_IRWXG 00070权限,代表该文件用户组具有可读、可写及可执行的权限。
S_IRGRP 00040 权限,代表该文件用户组具有可读的权限。
S_IWGRP 00020权限,代表该文件用户组具有可写入的权限。
S_IXGRP 00010 权限,代表该文件用户组具有可执行的权限。
S_IRWXO 00007权限,代表其他用户具有可读、可写及可执行的权限。
S_IROTH 00004 权限,代表其他用户具有可读的权限
S_IWOTH 00002权限,代表其他用户具有可写入的权限。
S_IXOTH 00001 权限,代表其他用户具有可执行的权限。
open 返回的文件描述符一定是最小的未被使用的描述符。
2. close 函数
用于关闭已打开的文件。
头文件: #include <unistd.h>
函数原型: int close(int fd);
返回值: 0(成功)或者 -1(出错)
fd: 是要关闭的文件描述符。
进程结束时,该进程打开的所有文件都会自动被内核(kernel)关闭。
//文件打开与关闭2008.12.06
#include
#include
#include
#include
#include
#include
int main(void)
{
int fd;
//调用open,以可读写方式打开
if((fd=open("/tmp/hello1.c",O_CREAT|O_TRUNC|O_RDWR,0700))<0){
perror("open:");
exit(1);
}
else{
printf("open file:hello1.c %d\n",fd);
}
//close
if(close(fd)<0){
perror("close:");
exit(1);
}
else{
printf("close hello1.c\n");
}
exit(0);
}
(3)read函数(读取文件中指定大小的数据)
#include
ssize_t read(int fd,void *buf,size_t count);
参数:
fd:将要读取的数据的文件描述符
buf:所要读取到的数据的内存缓冲
count:需要读取的数据量
返回说明:
成功执行时,返回所读取的数据量,如果读到文件的末尾则返回0。失败的时候返回-1。
(4)write()函数
写函数write
ssize_t write(int fd,const void *buf,size_t nbytes)
write函数将buf中的nbytes字节内容写入文件描述符fd.成功时返回写的字节数.失败时返回-1. 并设置errno变量. 在网络程序中,当我们向套接字文件描述符写时有俩种可能.
1)write的返回值大于0,表示写了部分或者是全部的数据.
2)返回的值小于0,此时出现了错误.我们要根据错误类型来处理. 如果错误为EINTR表示在写的时候出现了中断错误.
(5)lseek函数:为一个打开的文件设置其偏移量
#include
函数说明:每一个已打开的文件都有一个读写位置,当打开文件时通常其读写位置是指向文件开头,若是以附加的方式打开文件(如O_APPEND),则读写位置会指向文件尾。当read()或write()时,读写位置会随之增加,lseek()便是用来控制该文件的读写位置。参数fildes 为已打开的文件描述词,参数offset 为根据参数whence来移动读写位置的位移数。
whence为下列其中一种:(SEEK_SET,SEEK_CUR和SEEK_END和依次为0,1和2).
SEEK_SET 将读写位置指向文件头后再增加offset个位移量。 SEEK_CUR 以目前的读写位置往后增加offset个位移量。 SEEK_END 将读写位置指向文件尾后再增加offset个位移量。 当whence 值为SEEK_CUR 或SEEK_END时,参数offet允许负值的出现。 下列是教特别的使用方式: 1) 欲将读写位置移到文件开头时: lseek(int fildes,0,SEEK_SET); 2) 欲将读写位置移到文件尾时: lseek(int fildes,0,SEEK_END); 3) 想要取得目前文件位置时: lseek(int fildes,0,SEEK_CUR); 返回值:
当调用成功时则返回目前的读写位置,也就是距离文件开头多少个字节。若有错误则返回-1,errno 会存放错误代码。
Linux系统不允许lseek()对tty装置作用,此项动作会令lseek()返回ESPIPE。
(6)dup()、dup2()函数:功能就是复制文件描述符
(7)fsync()函数:fsync函数,将文件数据同步到硬盘
功能描述:
系统调用fsync将所有已写入文件描述符fd的数据真正的写道磁盘或者其他下层设备上。
用法:
#include
int fsync(int fd);
#ifdef _POSIX_SYNCHRONIZED_IO
int fdatasysnc(int fd);
#endif
参数:
fd:文件描述符。
返回说明:
成功执行时,返回0。失败返回-1,errno被设为以下的某个值
EBADF: 文件描述词无效
EIO : 读写的过程中发生错误
EROFS, EINVAL:文件所在的文件系统不支持同步
sync(将缓冲区数据写回磁盘)
相关函数 :fsync
表头文件 :#include
定义函数 :int sync(void)
函数说明 :sync()负责将系统缓冲区数据写回磁盘,以确保数据同步。
返回值 :成功的是时候返回0。
(9)fcntl()函数:用来改变已打开文件的性质
fcntl 函数语法要点
所需头文件
#include函数原型 : int fcnt1(int fd, int cmd, struct flock *lock)
#include
fd: 文件描述符
cmd: F_DUPFD:复制文件描述符
F_GETFD:获得 fd 的 close-on-exec 标志,若标志未设置,则文件经过 exec函数之后仍保持打开状态
F_SETFD:设置 close-on-exec 标志,该标志以参数 arg 的 FD_CLOEXEC 位决定
F_GETFL:得到 open 设置的标志
F_SETFL:改变 open 设置的标志
F_GETFK:根据 lock 描述,决定是否上文件锁
F_SETFK:设置 lock 描述的文件锁
F_SETLKW:这是 F_SETLK 的阻塞版本(命令名中的 W 表示等待(wait) 。)如果存在其他锁,则调用进程睡眠;如果捕捉到信号则睡眠中断
F_GETOWN:检索将收到 SIGIO 和 SIGURG 信号的进程号或进程组号
F_SETOWN:设置进程号或进程组号