优质服务商推荐更多服务商>

需要了解Linux下的文件I/O编程

3816

    linux   下C语言对于文件的操作,我们会经常用到fopen(),fclose(),fwri     te   (),fread(),fgets()等一系列库函数,基本和是和windows下学习C语言一样的,其实这些库函数就是在linuxx下对系统调用函数的封装,因此这里只介绍系统函数下的文件操作函数。

 需要了解Linux下的文件I/O编程_设计制作_接口/总线/驱动

(一).open()打开文件

#include #include #includeint open(const char *pathname, int flags);

参数1:pathname,文件所在路径

参数2:flags,文件权限,相对于程序进程

常见宏为:O_WRONLY,O_RDONLY,O_RDWR,O_EXCL,O_APPEND,O_DUMP

参数3:mode,当创建文件时候使用,一般为umask的值。

返回值: 成功返回文件描述符,否则返回-1.

(二)close,关闭一个文件。参数为文件描述符

#includeint close(int fd);

(三)write,向文件中写数据

#includessize_t write(int fd, const void *buf, size_t count);

fd: 文件描述符

buf:存储将要写的数据

count: 写入的长度,以字节为单位

返回值:写入成功时,返回写入的     字符   长度,否则返回-1。

(四)read,读文件中数据

#includessize_t read(int fd, void *buf, size_t count);

fd: 文件描述符

buf:存储将要读入的数据

count: 读出的长度,以字节为单位

返回值:读成功时,返回读出的字符长度,否则返回-1。

例如:

#include

(五)lseek,修改文件偏移量

#include #include

fd: 文件描述符

offset:将要偏移 的字节数。

whence:从那开始偏移,宏定义如下:

SEEK_END 文件末尾

SEEK_CUR 当前偏移量位置

SEEK_SET 文件开头位置

注意:当偏移量大于文件长度时,产生     空洞   ,空洞是由所设置的偏移量超过文件尾端,并写了一些数据造成了,其从原文件尾端到新偏移的位置之间即是产生的空洞。空洞不占用磁盘空间,可以使用:

du filename #查看文件所占实际磁盘空间ls filename #实际文件的大小

例如:

#include#include#include#include #include #include#define BUFF 12int m     ai   n(){char str1[BUFF] = “jign     ti   kai”;char str2[BUFF] = “wojisuhihawe”;int fd;if ( (fd = open(“a.txt”,O_WRONLY|O_CREAT,0744)) ={perror(“open file fail\n”);exit(EXIT_FAILURE);}if( write(fd,str1,BUFF) == -1 ){perror(“write fial fail\n”);exit(EXIT_FAILURE);}if( lseek(fd,1024,SEEK_END) == -1 ){perror(“lseek fail\n”);}write(fd,str2,BUFF);return 0;}

(六)access 判断文件是否具有读,写,可执行或者是否存在

#includeint access(const char *pathname, int mode);

pathname: 文件名

mode 可以选择以下宏:

F_OK 文件是否存在

R_OK 文件否具有读权限

X_OK 文件否具有可执行权限

W_OK 文件否具有写权限

返回值:满足mode中的参数并且正确执行则返回0 ,否则返回-1。

(七)dup或dup2,创建一个文件描述符,其指向同一个文件表

#includeint dup(int oldfd);

oldfd:原来的文件描述符

newfd:指定新的文件描述符数值,如果该描述已经存在则先将其关闭,若oldfd等于newfd,ze返回newfd,而不关闭。

在此简单介绍一下文件的内核结构:首先计算机系统中有一个进程表,其中的每个进程表项,该表项中有一个打开文件描述符表,该打开的文件描述表中有很多文件描述符表项,每项包括两部分:文件描述符标志与文件指针,其中文件指针指向一个文件表,文件表中存放着文件的状态标志即是否可读是否可写,当前文件的偏移量,还有一个v节点指针,指针v节点指针指向一个v节点表,v节点表主要存放文件的所有者,文件长度,文件的设备以及文件实际数据块在磁盘上的位置等一系列信息。可能这样描不太清楚,下面用一张图来描述:

 需要了解Linux下的文件I/O编程_设计制作_接口/总线/驱动

(八)sync与fsync

(对于以下会主要是针对的内核缓冲)由于io操作会首先将数据放入内核缓冲区,所以在写的时候如果出现系统故障则缓冲区的数据可能会丢失,所以为了防止这种情况发生,以上两个函数使得内核缓冲区的数据立即写入磁盘。

#includevoid sync(void);将所有缓冲排入写队列,然后立即返回int fsync(int fd);将所有缓冲排入写队列,直到该缓冲去的数据写入磁盘后才返回。int fdatasync(int fd);几乎和fsync函数相同,只是fdatasync(int fd)函数只影响数据部分,而fsync还会同步更新文件的属性。

(九)fcntl函数,该函数可以改变已经发开文件的性质

#include#includeint fcntl(int fd, int cmd, 。.. /* arg */ );

fd:文件描述符

cmd 指明该函数执行什么功能

F_DUPFD 赋值文件描述符,功能相当于dup和dup2函数。例如:

dup(fd)等价于

fcntl(fd,F_DUPFD,0)

dup2(oldfd,newfd)等价于

close(newfd);

fcntl(oldfd,F_DUPFD,newfd);

F_GETFD 的到文件描述符标志,当前之定义一个文件描述符标志,FD_CLOSEEXEC.此时第三个参数被忽视。

F_SETFD 设置文件描述符标志,设置的值是函数的第三个参数,其一般可设置为0表示关闭,1表示打开。

F_SETFL 设置文件状态标志,其值放在函数的第三个参数,和open函数第二个参数的值一样的。

F_GETFL 得到文件状态标志。此时第三个参数被忽视。

arg 可选参数,根据第二个参数填写。

返回值:出错返回-1,否则哈返达到的标志。

例如:

#include#include#include#includeint main(int argc,char * argv[]){int fd;int val=3;if( (fd = open(argv[1],O_RDWR|O_APPEND)) == -1 )//     测试   一下是否可以同时检测出文件的读写属性{exit(2);}if( val = fcntl(fd,F_GETFL,0) == -1 ){exit(1);}printf(“%d\n”,val);printf(“%d %d %d\n”,O_RDONLY,O_WRONLY,O_RDWR);int n = val & O_ACCMODE;if( n == O_RDONLY)printf(“read\n”);if(O_WRONLY & val )printf(“write\n”);if( n == O_RDWR)printf(“read and write\n”);}

(十)最后再说一下Linux缓冲的问题吧

linux中有两个级别的缓冲:IO缓冲与内核缓冲

(1)IO缓冲:对于标准IO操作,都会有一个缓冲区,当用户想要写数据时,首先将数据写入缓冲区,待缓冲区满之后才能调用系统函数写入内核缓冲区。当用户想读取数据时,首先向内核读取一定的数据放入IO缓冲区,读操作从缓冲区中读数据,当读完IO缓冲区的数据时,才能再读取数据到IO缓冲区。

目的:减少对磁盘的读写次数,提高工作效率。

(2)内核缓冲区:操作系统内核部分也有缓冲,其与IO缓冲区是不同的,其主要区别用一张图表示:

 需要了解Linux下的文件I/O编程_设计制作_接口/总线/驱动

特别声明:本文仅供交流学习 , 版权归属原作者,并不代表蚂蚜网赞同其观点和对其真实性负责。若文章无意侵犯到您的知识产权,损害了您的利益,烦请与我们联系vmaya_gz@126.com,我们将在24小时内进行修改或删除。

相关推荐: