Linux 文件操作接口

在使用语言编写服务的时候不乏会遇到需要对文件进行操作的场景,Linux内核是用C语言写的,了解Linux之前先熟悉一下C语言文件操作接口,方便对比。

C语言文件操作接口

C语言文件描述

#ifndef _FILE_DEFINED
struct _iobuf {
    char *_ptr; //文件输入的下一个位置
    int _cnt; //当前缓冲区的相对位置
    char *_base; //指基础位置(即是文件的起始位置)
    int _flag; //文件标志
    int _file; //文件描述符id
    int _charbuf; //检查缓冲区状况,如果无缓冲区则不读取
    int _bufsiz; //文件缓冲区大小
    char *_tmpfname; //临时文件名
};
typedef struct _iobuf FILE;
#define _FILE_DEFINED
#endif

C语言对文件操作需要的数据都存在这样的数据结构里,C语言对文件操作时,用一个数据结构唯一标识一个文件流

fopen()

FILE* fopen(const char *path, const char *mode);

返回值为文件流结构体指针,当打开失败时返回NULL指针。

对文件操作前需先打开文件,打开文件使用接口fopen()。

参数:

path: 文件路径,可以是相对路径也可以是绝对路径(默认为进程打开时路径)

mode: 打开方式

模式 含义 文件不存在时
r 只读 报错
w 只写 创建文件
a 追加只写 创建文件
rb 二进制只读 报错
wb 二进制只写 创建文件
ab 二进制追加只写 创建文件
r+ 读写 报错
w+ 读写 创建文件
a+ 追加读写 创建文件
rb+ 二进制读写 报错
wb+ 二进制读写 创建文件
ab+ 二进制追加读写 创建文件

以上打开模式凡带'b'操作的打开文件时都会清空文件。

r模式打开文件

)

文件不存在时打开失败



文件存在时打开成功

w模式打开文件



自动创建需要打开的文件



打开后会清空文件

a模式打开文件

以a模式打开文件不存在时创建文件,存在时在文件末尾写入内容。

其他模式类似

fclose()

C语言程序员要养成用完即释放的好习惯尽量避免内存泄漏,fclose() 接口就是用来关闭文件流的。

int fclose(FILE *fp);

关闭接口参数简单,只需将需要关闭的文件流指针传入即可。

fwrite()

size_t fwrite(const void *ptr, size_t size, size_t number, FILE *stream);

参数:

ptr: 写入文件的内容

size: 写入单位数据大小(byte)

number: 写入数据总数

stream: 文件流

写入操作传参如图

fread()

size_t fread(void *ptr, size_t size, size_t number, FILE *stream);

参数类似fwrite()

ptr 为要读入文件内容的容器,必须提前开好空间,number 不得大于实际开好的空间

读文件操作如图

系统文件操作接口

文件描述符fd

文件描述符可以唯一标识该进程打开的流。

open()

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

参数:

pathname: 文件路径,默认为进程创建时的路径

flags: 决定文件打开模式

mode: 创建文件时文件权限

理解标记位原理

计算机中所有数据都由比特位组成,一个整形有32个比特位,用一位作为标记,一个int类型可以携带32个标识,并且可以随意组合。

如下操作,想完成什么操作传入对应的标记即可。

open()的常用标记

标记 含义
O_RDONLY 只读
O_WRONLY 只写
O_RDWR 读写
O_APPEND 追加
O_CREAT 创建文件
O_TRUNC 清空文件

将只读标记和创建文件标记传入open()接口,创建文件如图。文件创建出来了,但可以看出它的权限是乱的,可见这个接口不足以像fopen() 一样打开文件。

使用另一个接口创建出来权限正常的文件,但权限还不是如我们所设想的设置什么权限码就创建什么权限文件。此问题与权限掩码umask有关

权限码与umask取反再按位与最后得到的权限码才是最终权限码,若需只在该程序重设umask 只需使用接口umask:

mode_t umask(mode_t mask);

参数mask为想要重设的权限掩码

现在所创建的文件权限就全如程序员所愿了。

write()

系统写文件操作接口

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

操作与fwrite() 基本一致,参数buf 类型为void* ,count 为要写入内容大小(byte)。

写入成功,但如上打开方式还有一个隐患:

后写入的内容并不会在空文件写入,而是会在已有内容上进行覆盖,这样的操作可不像C语言的w操作,针对此问题可以再加一个标志O_TRUNC

如此才可和C语言的fopen() 的 w 操作一致

read()

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

read()参数与write() 基本一致,与fread() 操作相差不多,需要buf 提前开好空间

当文件不存在时:

如此,效果与fread() 一致

close()

使用完文件后需得关闭文件,尽量防止内存泄漏,使用close()接口

int close(int fd);

两种操作接口联系

操作系统设计时为了安全任何高级语言操作文件都不能绕过操作系统,用户对文件操作只能通过操作系统提供的接口,而Linux操作系统内核主要用C语言编写,提供的接口也是用C语言编写的,C语言用户可以直接使用。C语言操作文件也需通过操作系统提供的接口,因此C语言的文件操作接口是对系统文件接口进行封装后暴露出来的。

但既然已经有系统接口了为什么还要C语言文件操作接口,此问题原因有几个:

  1. 使用不方便(对比之前的fopen()open())
  2. C语言是跨平台语言,若使用系统文件操作接口,同一份代码移植到其他平台将会编译不通过,使用封装后的接口,可以完美解决这个问题

高级语言都是用自己的语言特性封装系统接口来操作文件

系统接口 语言接口
open(const char* path, O_WRONLY | O_CREAT | O_TRUNC) fopen(const char* path, "w")
open(const char* path, O_RDONLY) fopen(const char* path, "r")
open(const char* path, W_WRONLY | O_CREAT |O_APPEND) fopen(const char* path, "a")
close(int fd) fclose(FILE* fStream)
write(fd, const void* buf, size_t count) fwrite(const void* ptr, size_t size, size_t number, FILE* fStream)
read(fd, void* buf, size_t count) fread(void* ptr, size_t size, size_t number, FILE* fStream)

C语言对封装的接口跨平台解决办法

条件编译 + 穷举

Linux 文件操作接口的更多相关文章

  1. C/C++以及Linux文件操作备忘录

    目录 C文件操作 文件开关 文件读写 C++文件操作 Linux文件操作 打开 C文件操作 #include<stdio.h> stdin, stdout, stderr 文件开关 /* ...

  2. Linux文件操作的主要接口API及相关细节

    操作系统API: 1.API是一些函数,这些函数是由linux系统提供支持的,由应用层程序来使用,应用层程序通过调用API来调用操作系统中的各种功能,来干活 文件操作的一般步骤: 1.在linux系统 ...

  3. Linux 文件操作监控inotify功能及实现原理【转】

    转自:http://blog.chinaunix.net/uid-26585427-id-5012973.html 1. inotify主要功能 它是一个内核用于通知用户空间程序文件系统变化的机制. ...

  4. Linux 文件操作总结

    http://blog.163.com/he_junwei/blog/static/19793764620152592737741/ ioctl?? lseek?? 文件是linux中的一个重要概念. ...

  5. Linux文件操作学习总结【转载】

    本文转载自: http://blog.csdn.net/xiaoweibeibei/article/details/6556951 文件类型:普通文件(文本文件,二进制文件).目录文件.链接文件.设备 ...

  6. 关于文件的INode与Java中的文件操作接口

    本文由作者周梁伟授权网易云社区发布. 近日做的项目中涉及到多进程共同读写多个文件的问题,文件名和最后修改时间都是可能会被频繁修改的,因而识别文件的唯一性会产生相当的麻烦,于是专门再学习了一下文件系统对 ...

  7. Linux 文件操作——系统调用和标准I/O库

    一.什么是文件 在讲述文件操作之前,我们首先要知道什么是文件.看到这个问题你可能会感觉到可笑,因为对于用过计算机的人来说,文件是最简单不过的概念了,例如一个文本是一个文件,一个work文档是一个文件等 ...

  8. linux 文件操作与目录操作

    文件操作 使用命令 命令格式: 命令 [选项] [参数] [] 表示可选的 示例: ls -a /etc 常识命令 ls:查看指定目录的内容,不指定目录时查看当前工作目录 选项 说明 -a 显示所有文 ...

  9. Linux文件操作常用命令整理

    收集.整理日常系统管理或维护当中的,常用到的一些关于文件操作的命令或需求,后续会慢慢补充.完善! 查看.生成指定目录的目录树结构?   [root@DB-Server ~]#tree   #当前目录 ...

随机推荐

  1. MES对接Simba实现展讯平台 IMEI 写号与耦合测试

    文章开始之前,必须对Simba工具点一个大大的赞,Simba为了适应市面上不同厂家开发的 MES 系统,特地开发了统一的接口,各个 MES 厂家只需要按照接口规范去做开发,然后将中间件加载到 Simb ...

  2. 新一代工作流调度-Apache DolphinScheduler 1.3.5 Docker镜像发布

    新一代大数据工作流调度 - Apache DolphinScheduler(incubator) 今天发布了 1.3.5 官方 Docker 镜像.在社区伙伴 chengshiwen 的努力下,  1 ...

  3. Linux 02 基本命令

    参考源 https://www.bilibili.com/video/BV187411y7hF?spm_id_from=333.999.0.0 版本 本文章基于 CentOS 7.6 工具 清屏 cl ...

  4. 微软Azure配置中心 App Configuration (三):配置的动态更新

    写在前面 我在前文: <微软Azure配置中心 App Configuration (一):轻松集成到Asp.Net Core>已经介绍了Asp.net Core怎么轻易的接入azure ...

  5. 大家都能看得懂的源码 - 那些关于DOM的常见Hook封装(一)

    本文是深入浅出 ahooks 源码系列文章的第十四篇,该系列已整理成文档-地址.觉得还不错,给个 star 支持一下哈,Thanks. 上一篇我们探讨了 ahooks 对 DOM 类 Hooks 使用 ...

  6. 超详细 VS Code 配置C/C++教程

    写在前面 如果您使用的电脑内存 \(\leq 4 \texttt{GB}\),建议您使用Dev-C++,否则会到时内存占用爆满,体验感不佳. 网上的很多教程都不够详细,这里我把每一步.每一个操作都详细 ...

  7. KFS邮件自动告警-数据比对-数据修复配置方法

    一.告警机制 用户可以通过配置告警机制,在比对完成和节点报错时接收到邮件告警. 告警机制共包含3个方面: 1. 告警配置 2. 用户订阅 3. 告警历史 KFS邮箱分两个部分,一个是接收告警信息的邮箱 ...

  8. PHP 使用AES加密,并扩展失效时间检测

    /** * 具有时间校验的AES加密 * @param string $string 要处理的字符串 * @param int $timeout 超时时间,单位秒 * @param string $t ...

  9. Docker 部署 RocketMQ 双主双从模式( 版本v4.7.0)

    文章转载自:http://www.mydlq.club/article/96/ 系统环境: 系统版本:CentOS 7.8 RocketMQ 版本:4.7.0 Docker 版本:19.03.13 一 ...

  10. 在 AlertManager 报警通知中展示监控图表

    原文档地址:https://mp.weixin.qq.com/s/Wcp7ltEbnHpUlbaF9JDgZg 去绘制渲染报警图表,然后上传到对象存储中保存起来,在钉钉中就可以直接展示了,Promot ...