unix环境下的文件操作的一些函数open()、close()、read()、write()、dup()、fsync()sync()函数

时间:2021-04-30 19:08:22

不带缓存的文件I/O操作主要有5个函数open、read、write、lseek和close。这几个不带缓存的操作是指每一个函数都只调用系统中的一个函数。这些函数不是ANSIC组成部分,但属于POSIX的组成部分。

1.open函数(返回的文件描述符一定是最小的且没有被用过的数值)

open 函数用于打开和创建文件。

所需都文件

#include<sys/types.h>//提供pid_t类型的定义

#include<sys/stat.h>

#include<fcntl.h>

函数原型 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<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>
#include<stdio.h>

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<unistd.h>

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<unistd.h>

#include<sys/types.h>
函数的定义:off_t lseek(int fildes,off_t offset ,int whence);
函数说明:每一个已打开的文件都有一个读写位置,当打开文件时通常其读写位置是指向文件开头,若是以附加的方式打开文件(如O_APPEND),则读写位置会指向文件尾。当read()或write()时,读写位置会随之增加,lseek()便是用来控制该文件的读写位置。参数fildes 为已打开的文件描述词,参数offset 为根据参数whence来移动读写位置的位移数。

  Offset:偏移量,每一读写操作所需要移动的距离,单位是字节的数量,可正可负(向前移,向后移)。
参数:  

       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 <unistd.h> 

int fsync(int fd);

#ifdef _POSIX_SYNCHRONIZED_IO

    int fdatasysnc(int fd);

#endif
参数: 
fd:文件描述符。 
返回说明: 
成功执行时,返回0。失败返回-1,errno被设为以下的某个值 
EBADF: 文件描述词无效 
EIO : 读写的过程中发生错误 
EROFS, EINVAL:文件所在的文件系统不支持同步

(8)sync()函数:

sync(将缓冲区数据写回磁盘) 
相关函数 :fsync 
表头文件 :#include<unistd.h> 
定义函数 :int sync(void) 
函数说明 :sync()负责将系统缓冲区数据写回磁盘,以确保数据同步。 
返回值 :成功的是时候返回0。

(9)fcntl()函数:用来改变已打开文件的性质

fcntl 函数语法要点
所需头文件 

#include <unistd.h>
#include <fcntl.h>
函数原型 : int fcnt1(int fd, int cmd, struct flock *lock)

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:设置进程号或进程组号
 转载自:http://blog.csdn.net/liangxanhai/article/details/7749170