阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Linux下的文件I/O编程

81次阅读
没有评论

共计 3391 个字符,预计需要花费 9 分钟才能阅读完成。

导读 linux 下 C 语言对于文件的操作,我们会经常用到 fopen(),fclose(),fwrite(),fread(),fgets() 等一系列库函数,基本和是和 windows 下学习 C 语言一样的,其实这些库函数就是在 linuxx 下对系统调用函数的封装,因此这里只介绍系统函数下的文件操作函数。
(一).open() 打开文件
#include <sys/types.h>
#include <sys/stat.h>
#include
int 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,关闭一个文件。参数为文件描述符
#include
int close(int fd);
(三)write, 向文件中写数据
#include
ssize_t write(int fd, const void *buf, size_t count);

fd: 文件描述符
buf: 存储将要写的数据
count: 写入的长度,以字节为单位
返回值:写入成功时,返回写入的字符长度,否则返回 -1。

(四)read,读文件中数据
#include
ssize_t read(int fd, void *buf, size_t count);

fd: 文件描述符
buf: 存储将要读入的数据
count: 读出的长度,以字节为单位
返回值:读成功时,返回读出的字符长度,否则返回 -1。
例如:
#include

(五)lseek,修改文件偏移量
#include <sys/types.h>
#include <unistd.h
off_t lseek(int fd, off_t offset, int whence);

fd: 文件描述符
offset:将要偏移 的字节数。
whence:从那开始偏移,宏定义如下:
SEEK_END 文件末尾
SEEK_CUR 当前偏移量位置
SEEK_SET 文件开头位置
注意: 当偏移量大于文件长度时,产生空洞,空洞是由所设置的偏移量超过文件尾端,并写了一些数据造成了,其从原文件尾端到新偏移的位置之间即是产生的空洞。空洞不占用磁盘空间,可以使用:

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

例如:

#include
#include
#include
#include <sys/types.h>
#include <sys/stat.h>
#include

#define BUFF 12
int main()
{char str1[BUFF] = "jigntikai";
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 判断文件是否具有读,写,可执行或者是否存在
#include
int access(const char *pathname, int mode);

pathname:文件名
mode 可以选择以下宏:
F_OK 文件是否存在
R_OK 文件否具有读权限
X_OK 文件否具有可执行权限
W_OK 文件否具有写权限
返回值:满足 mode 中的参数并且正确执行则返回 0,否则返回 -1。

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

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

(八)sync 与 fsync

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

#include
void sync(void); 将所有缓冲排入写队列,然后立即返回
int fsync(int fd); 将所有缓冲排入写队列,直到该缓冲去的数据写入磁盘后才返回。int fdatasync(int fd); 几乎和 fsync 函数相同,只是 fdatasync(int fd) 函数只影响数据部分,而 fsync 还会同步更新文件的属性。
(九)fcntl 函数,该函数可以改变已经发开文件的性质
#include
#include
int 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
#include

int 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 编程

 

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-07-24发表,共计3391字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中