一、文件操作方法

linux中有两种方法可以操作文件:系统调用和c库函数。

1. 什么是系统调用?

由操作系统实现并提供给外部应用程序的编程接口(API),是应用程序同系统之间数据交互的桥梁。

C标准函数和系统函数调用关系,如图:

2. c库函数

待写。

二、文件IO(系统调用API)

库函数头文件统一使用头文件unistd.h

1. open创建

头文件:

#include <fcntl.h>

函数原型:

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

参数说明:

  • pathname:文件名
  • flag:文件打开标志
flag参数 说明
O_RDONLY 只读方式打开
O_WRONLY 只写方式打开
O_RDWR 可读可写
O_CREAT 文件不存在则创建(文件权限由mode参数指定)
O_APPEND 追加方式写入
O_EXCL 判断文件是否存在
O_TRUNC 截断文件大小为0/清空文件
O_NONBLOCK

mode权限参数说明:

  1. 该参数使用八进制指定;
  2. 该参数受umask(默认0002)影响:最终权限 = mode &~ umask,其实就是把我们所指定权限中other用户的写权限给去除。

返回值说明:

  • 成功返回fd号
  • 失败返回-1,错误原因errno给出

2. close关闭

头文件:

#include <unistd.h>

函数原型:

int close(int fd);

参数说明:

  • fd:文件描述符

3. write写入

头文件:

#include <unistd.h>

函数原型:

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

参数说明:

  • fd:文件描述符
  • buf:待写数据指针
  • count:待写数据大小

返回值:

  • 成功:返回写入的字节数
  • 失败:返回-1,error被设置

4. read读取

头文件:

#include <unistd.h>

函数原型:

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

参数说明:

  • fd:文件描述符
  • buf:缓冲区指针
  • count:要读取的数据大小

返回值:

  • 成功:返回读取的字节数
  • 失败:返回-1,error被设置

说明:

在支持查找的文件上,读取操作从文件偏移量开始,并且文件偏移量会随着读取递增。如果文件偏移量在文件末尾或者超过文件末尾,则返回0

5. lseek文件偏移

头文件:

#include <unistd.h>

函数原型:

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

参数说明:

  • fd:文件描述符
  • offset:偏移量
  • count:要读取的数据大小
    • SEEK_SET:The file offset is set to offset bytes.
    • SEEK_CUR:The file offset is set to its current location plus offset bytes.
    • SEEK_END:The file offset is set to the size of the file plus offset bytes.

返回值:

  • 成功:返回当前所在偏移量
  • 失败:返回-1,error被设置

三、测试程序

demo1——默认创建文件的权限

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>int main(int argc, char *argv[])
{int fd;fd = open("hello.txt", O_RDWR | O_CREAT);printf("fd is %d\n", fd);close(fd);return 0;
}

执行结果:

fd is 3

如果hello.txt不存在,则open会创建该文件,但我们并没有指定文件权限(mode),查看默认创建文件的权限:

---Srwx--T 1 ubuntu ubuntu    0 Sep  5 16:40 hello.txt

后续文件权限分析?

demo2——指定创建文件的权限

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>int main(int argc, char *argv[])
{int fd;// 0644: rw-r--r--fd = open("hello.txt", O_RDWR | O_CREAT, 0644);printf("fd is %d\n", fd);close(fd);return 0;
}

执行之后再次查看hello.txt的权限:

rw-r--r-- 1 ubuntu ubuntu    0 Sep  5 16:47 hello.txt

demo3——指定创建文件的权限受umask影响

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>int main(int argc, char *argv[])
{int fd;// 0777: rwxrwxrwx// umask: 0002fd = open("hello.txt", O_RDWR | O_CREAT, 0777);printf("fd is %d\n", fd);close(fd);return 0;
}

创建出的hello.txt权限为:

-rwxrwxr-x 1 ubuntu ubuntu    0 Sep  5 17:03 hello.txt*

demo4-打开文件出错

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>int main(int argc, char *argv[])
{int fd;fd = open("hello.txt", O_RDWR);printf("fd is %d\n", fd);printf("errno is %d(%s)\n", errno, strerror(errno));close(fd);return 0;
}

当hello.txt不存在时,日志为:

fd is -1
errno is 2(No such file or directory)

demo5——文件偏移量导致读取失败

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>int main(int argc, char *argv[])
{int fd;int nbytes;char write_buf[] = "helloworld!";char read_buf[1024] = {0};/* 1. open file */fd = open("hello.txt", O_RDWR | O_CREAT, 0664);if (fd < 0) {printf("open fail, fd is %d\n", fd);printf("errno is %d(%s)\n", errno, strerror(errno));return -1;}/* 2. write */nbytes = write(fd, write_buf, sizeof(write_buf));if (nbytes < 0) {printf("write fail, errno is %d(%s)\r\n", errno, strerror(errno));return -1;}printf("write %d bytes\r\n", nbytes);/* 3. read */nbytes = read(fd, read_buf, sizeof(read_buf));if (nbytes < 0) {printf("read fail, errno is %d(%s)\r\n", errno, strerror(errno));return -1;}printf("read %d bytes:[%s]\r\n", nbytes, read_buf);/* 4. close */close(fd);return 0;
}

write写入完成后,文件偏移量在文件末尾,直接读取导致返回0:

write 12 bytes
read 0 bytes:[]

这个时候在read之前,使用lseek函数将文件偏移量恢复到文件开始处即可:

lseek(fd, 0, SEEK_SET);

Linux系统编程 | 01 -文件操作相关推荐

  1. 【Linux系统编程】文件描述符的复制dup()和dup2()

    00. 目录 文章目录 00. 目录 01. 文件描述符复制概述 02. 常用函数 2.1 dup函数 2.2 dup2函数 03. 案例实战 3.1 dup示例 3.2 dup2示例 04. 附录 ...

  2. Linux系统编程之文件IO

    Linux系统编程之文件IO 文件IO第一天 一.标准IO基本概念 1.1c语言函数 (c库函数) 调用实现某一个功能,(API) 1.2系统调用:内核中的程序接口,应用程序和硬件设备之间的中间层 1 ...

  3. linux系统编程之文件与I/O(六):fcntl 函数与文件锁

    2013-05-14 11:26 8290人阅读 评论(2) 收藏 举报  分类: linux系统编程(19)  版权声明:本文为博主原创文章,未经博主允许不得转载. 一.fcntl函数 功能:操纵文 ...

  4. 黑马程序员-Linux系统编程-01

    课程链接 01-Linux命令基础习惯-Linux系统编程_哔哩哔哩_bilibili 课程重点笔记 01-linux命令基础习惯 终端 终端:一切输入.输出的总称,因此终端并不是一定指的是命令行,只 ...

  5. linux系统io编程,Linux系统编程(1) —— 文件IO

    本文主要对Linux系统中文件I/O的基本操作进行说明. 在Linux系统编程中,对文件进行处理的流程,通常是: 打开文件 读写文件 关闭文件 Linux内核对每一个进程维护一个打开的文件列表, 该文 ...

  6. 【Linux | 系统编程】Linux系统编程(文件、进程线程、进程间通信)

    文章目录 Linux系统编程 文件IO open/close函数 read/write函数 文件描述符 阻塞.非阻塞 fcntl函数 lseek函数 传入传出参数 文件系统 文件存储 文件操作 sta ...

  7. Linux系统编程【文件IO、进程、进程间通信、信号、线程、互斥】

    linux系统编程 个人通过学习,手打了一份48000字的Linux系统编程的笔记,包含了[文件IO.进程.进程间通信.信号.多线程.互斥]等知识点,并给出了大量的代码案例对每个重要的知识点进行了代码 ...

  8. Linux系统编程.NO7——目录操作函数

    5. 目录文件管理函数 5.1. 目录文件概念 目录在Linux中也是文件,也有对应的文件指针,每次读目录之前也要先打开目录,然后目录指针就出现了,第一次读就是第一个文件的信息,然后第二次读就是第二个 ...

  9. 【Linux系统编程】文件IO操作

    文件描述符 在 Linux 的世界里,一切设备皆文件.我们可以系统调用中 I/O 的函数(I:input,输入:O:output,输出),对文件进行相应的操作( open().close().writ ...

最新文章

  1. python自动测试u_自动化测试——Selenium+Python之下拉菜单的定位
  2. 中科院信工所经验_2020计算机保研经验贴!(北航、北邮、中科院)
  3. 15分钟从零开始搭建支持10w+用户的生产环境(二)
  4. VS2017无法打开文件MSVCRTD.lib
  5. 电路板上的插头怎么拔下来_空调插头一直不拔费电吗?实测一周竟然发现了真相!...
  6. IIFP之牛刀小试(初识篇)
  7. linux命令大全-比较常用的
  8. Linux操作系统原理— 进程与线程管理
  9. Android 关于arm64-v8a、armeabi-v7a、armeabi、x86下的so文件兼容问题
  10. c语言 队列长度,c语言 队列
  11. 自己动手,更换光猫,这次是吉比特H2-3换为华为MA5671。(中国移动光纤宽带)
  12. C语言!鸡兔同笼的程序
  13. idea上传代码到github (图文并茂)
  14. composer.lock(锁文件)到底要不要提交到项目的版本库中?
  15. layui 上传图片 返回图片地址
  16. 字符串函数的模拟实现
  17. 知识图谱与推荐系统综述
  18. 赵小楼《天道》《遥远的救世主》深度解析(5)丁元英之所以能成为丁元英的条件的可能之一(一)
  19. 在Python中使用Elasticsearch
  20. 12讲 | STM32单片机控制继电器

热门文章

  1. VSCode下载及安装
  2. 智能电饭煲自动洗米手机操控一键搞定
  3. 10个常见的Android 新手误区
  4. web前端设计师需要常去的15个设计博客资源站
  5. 宽带DDC matlab,基于DDC和DUC的大带宽DRFM设计与实现
  6. compiz在debian上的安装和使用
  7. c语言20s计数器,供应电子计时器、JC20S、JY20S、计数控制器、计米器
  8. Arcmap矢量数据的基础编辑
  9. xson 1.0.2 发布,新增byte[] buffer,支持XCO
  10. 大于23的男生女生都该看.看完你会变一个人