linux文件IO函数大全

lunix中涉及文件IO的系统调用有:open、creat、close、write、read、fcntl、lseek。 


1、open :打开或创建一个文件

函数原型:

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

 int open(const char *pathname, int flags);
 int open(const char *pathname, int flags, mode_t mode);

返回值 :如果成功返回文件描述符,若出错返回-1

参数:pathname是要打开或创建的文件名称。

            oflag对应的文件状态标志都是定义在<fcntl.h>中的。man 2 open

            mode对应的是相关的文件权限模式,后面再讲。

注意:open返回的文件描述符一定是最小的未用描述符数值

 

2、creat : 创建一个新的文件

函数原型:

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

int creat(const char* pathname ,mode_t mode);

返回值:如果成功返回为只写打开的文件描述符,若出错则返回-1

               相当于:open(const char* pathname , O_WRONLY | O_CREAT | O_TRUNC , mode);所以一般就直接使用open,而不再使用creat。


3、close : 关闭一个打开的文件

函数原型:

#include <unistd.h>

int close(int filedes);

参数:filedes 要关闭的文件的文件的描述符

返回值:成功返回0,错误返回-1。

4、read:从打开的文件中读取数据

函数原型:

#include <unistd.h>

ssize_t read( int filedes , void* buf , size_t nbytes );

参数:filedes 文件描述符

            buf 存储读取到的字节内容的缓冲区

            nbytes 准备读取的字节数

返回值:如果调用成功返回实际的读取的字节数 ; 如果已到文件的结尾处则返回0 ; 发生错误   返回-1

其实read在读取文件时,一般都是通过循环,不断读入缓冲区的,所以如果上一次读取操作已经读到了文件的结尾处,那么这一次读取的时候,就会返回0,表明上一次读取已经到了文件的末尾。

这里void* 通用的指针类型,ssize_t 有符号的整数类型 size_t 非负的整数类型。

 

5、write:向打开的文件写数据

函数原型:

#include <unistd.h>

ssize_t write( int filedes , const void* buf , size_t nbytes );

参数:filedes 文件描述符

            buf 准备写入内容的缓冲区

            nbytes 准备写入的字节数

返回值:如果调用成功返回的是实际的写入的字节数 ; 如果发生错误发生 -1 

 

在牵涉到IO读取、写入的时候,如果为了提高IO的效率,那么read、write操作的buf大小最好设置为unix文件系统中块长的大小,这时候进行IO操作的CPU时间一般是最小的。(这是因为大多数文件系统为了改善其性能都采用某种预读(read ahead)技术,当检测到正在进行顺序读取时,系统就试图读入比应用程序所要求的更多的数据,并假设应用程序很快就会读这些数据)。例如:linux ext2文件系统的块长为4096个字节,块长由st_blksize决定。

 

下面是一个具体的例子:

  1. /* 
  2.  使用read函数读取文件内容 
  3.  使用write向文件中写内容 
  4.  text.txt是操作的文件对象 
  5. */  
  6. #include <stdio.h>  
  7. #include <unistd.h>  
  8. #include <fcntl.h>  
  9. #include <stdlib.h>  
  10. #include <string.h>  
  11.   
  12. #define MAX_LINE 1000  
  13.   
  14. int main(){  
  15.   
  16.     int fd ;  
  17.     fd = open("text.txt",O_RDWR );          //文件text.txt  
  18.   
  19.     char buf[MAX_LINE];  
  20.     ssize_t nbytes = read(fd , buf , MAX_LINE );    //read  
  21.     if( nbytes == -1 ){  
  22.         printf("read error!/n");  
  23.     }else if( 0 == nbytes ){  
  24.         printf("read the end of the file!/n");  
  25.     }  
  26.     else{  
  27.         printf("The total bytes read : %d /n",nbytes);  
  28.         printf("read buffer : /n/n%s",buf);  
  29.     }  
  30.           
  31.     char* code = "These words are writted by me!/n";  
  32.     nbytes = write(fd , code , strlen(code));   //write  
  33.     if( -1 == nbytes ){  
  34.         printf("write error!/n");  
  35.     }  
  36.     else{  
  37.         printf("/nThe total bytes write : %d /n/n" , nbytes );  
  38.     }  
  39.       
  40.     close(fd);  
  41.   
  42.   
  43.     return 0;  
  44. }  

 

6、fcntl : 可以改变已打开文件的属性

函数原型:

#include <fcntl.h>

int fcntl(int filedes , int cmd , ... /* int arg */) ;

返回值 : 如果成功则依赖于cmd,若错误则返回-1

第三个参数总是一个整数,与上面所示函数原型中的注释部分相对应。但是在作为记录锁用时,第三个参数则是指向一个结构的指针。
   fcntl函数有5种功能:
     1.复制一个现有的描述符(cmd=F_DUPFD).
     2.获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD).
     3.获得/设置文件状态标记(cmd=F_GETFL或F_SETFL).
     4.获得/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN).
     5.获得/设置记录锁(cmd=F_GETLK,F_SETLK或F_SETLKW).
记录锁相关的部分后面再讲解。。。。

fcntl返回的值与命令相关。如果出错,所有命令返回-1,如果成功则返回某个其他值。下面的四个命令有特定的返回值:F_DUPFD(返回新的文件描述符)、F_GETFD、F_GETFL(返回相应的标志)、F_GETOWN(返回一个正的进程ID或负的进程组ID)。

 

下面是一个例子:

 

  1. /* 
  2.  
  3.  这是一个使用fcntl函数的例子 
  4.  
  5.  对指定的文件描述符测试文件状态标志 
  6.  
  7. */  
  8.   
  9. #include <fcntl.h>  
  10.   
  11. #include <stdio.h>  
  12.   
  13. #include <stdlib.h>  
  14.   
  15.   
  16. int main(int argc , char* argv[]){  
  17.   
  18.   
  19. int val ;   
  20.   
  21.   
  22. if( argc != 2 )  
  23.   
  24. printf("usage: fcntl_example <file description#>. /n");  
  25.   
  26. //fcntl F_GETFL  
  27.   
  28. if( (val = fcntl(atoi(argv[1]) , F_GETFL , 0 ) ) < 0 ){  
  29.   
  30. printf("fcntl error for fd : %d ", atoi(argv[1]));  
  31.   
  32. }  
  33.   
  34.   
  35. switch( val & O_ACCMODE ){  
  36.   
  37.   
  38. case O_RDONLY :  
  39.   
  40. printf("read only /n");  
  41.   
  42. break ;  
  43.   
  44. case O_WRONLY :  
  45.   
  46. printf("write only /n");  
  47.   
  48. break ;  
  49.   
  50. case O_RDWR :  
  51.   
  52. printf("read and write /n");  
  53.   
  54. break ;  
  55.   
  56. default :  
  57.   
  58. printf("unknow access mode /n");  
  59.   
  60.   
  61. }  
  62.   
  63.   
  64. if( val & O_APPEND )  
  65.   
  66. printf(" , append /n");  
  67.   
  68. if( val & O_NONBLOCK )  
  69.   
  70. printf(" , noblock /n");  
  71.   
  72.   
  73. exit(0); //在linux中main函数正常退出都是使用exit(0),而在windows中一般都是使用return 0来标识main函数的退出。  
  74.   
  75. }  

 

下面还有一个例子:

 

  1. #include <fcntl.h>  
  2. #include <stdio.h>  
  3. #include <stdlib.h>  
  4.   
  5. int main(void){  
  6.   
  7.     int pd1 , fd ;  
  8.       
  9.     fd = open("fcntl_example2.c",O_RDWR);  
  10.     printf("orginal file descripion : %d /n",fd);   //3  
  11.          //fcntl F_DUPFD  
  12.     pd1 = fcntl(fd , F_DUPFD , 0);  
  13.     if( pd1 >=0 )  
  14.         printf("file description : %d/n" , pd1 );   //4 : 它是尚未打开的文件描述符中大于或等于fcntl第三个参数值(取为整数值)中各值的最小值  
  15.     exit(0);                                        //新描述符与filedes共享同一个文件表项,但是新文件描述符有它自己的一套文件描述符标志。  
  16.   
  17. }  

 

注意文件描述符标志和文件状态标志的区别

文件描述符标志指的是fd相关的属性,例如:FD_CLOEXEC等等。

而文件状态标志指的是文件本身的状态,例如:O_RDONLY、O_WRONLY、O_RDWR(三者互斥,只能在创建文件的时候指定其中一种状态标志,不能通过fcntl函数进行改变)其他可以改变的标志有:

O_APPEND           每次写时追加

O_NONBLOCK      非阻塞模式

O_SYNC               等待写同步(数据、文件属性)

O_DSYNC             等待写同步(数据)

O_RSYNC             同步读、写

返回值:如果成功返回 0 ,如果失败返回 -1

注意:当一个进程终止时,它会自动关闭所有打开的文件。很多程序利用这一点而不显式地调用close()关闭文件。

 

7、lseek :显式地为一个文件设置偏移量

函数原型:

#include <unistd.h>

off_t lseek(int filedes , off_t offset , int whence);

返回值:若成功则返回新的文件的偏移量,若错误则返回-1.

参数:  offset 它的类型是off_t,是带符号的类型,表示偏移量,在一般情况下可正可负。

             whence 它的取值为SEEK_SET(文件开头位置)、SEEK_CUR(当前文件偏移量位置)、SEEK_END(文件的结尾处)

 

注意:1、如果文件描述符引用的是一个管道、FIFO或网络套接字,则lseek返回-1,并将errno设置为ESPIPE。

            2、在默认情况下,除非设置open参数为O_APPEND,文件的偏移量位置总是设置为文件的开始位置。

 

最后说明:这里的文件IO操作:read、write被称为不带缓冲的IO,因为这些操作都在内核执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值