Linux系统编程——(1)文件IO基础

1、相关概念

文件IO也被称为不带缓存的IO
常用的五个文件IO分别为open、read、write、lseek、close函数,它们不是ISO C的组成部分,但是POSIX.1的组成部分。

1.1 UNIX 操作系统体系架构

1)SHELL:一种特殊的应用程序,为其他应用程序提供接口,例如ls,cp,mv等都是SHELL
2)公用函数库:公用函数库建立在系统调用接口之上
3)系统调用内核为用户空间提供的统一接口,使用时可以不用关心底层的硬件,同时也是内核为用户空间规定的访问通道,保障稳定和安全性
3)内核:控制计算机硬件资源,为程序提供运行环境。

在这里插入图片描述

1.2 文件描述符

所有打开的文件,都通过文件描述符(非负整数)应用,当打开或创建一个文件时,由内核向进程返回一个文件描述符,之后的文件IO操作,也都是对文件描述符进行操作。

其中,最前面的三个文件描述符,对应关系为:
标准输入(STDIN_FILENO) ->0
标准输出(STDOUT_FILENO)->1
标准错误(STDERR_FILENO)->2

这些常数定义在<unistd.h>中。

2、常用函数

2.1 open函数

打开或创建一个文件

#include <fcntl.h>

int open(const char *path, int oflag,/* int mode */)

path 文件路径
oflag 打开的操作
mode 权限(打开一个已存在的文件时,不需要该参数)

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

1)path 文件路径
该路径为绝对路径名,若只有文件名,则代表是相对路径名
2)oflag 打开的操作
以下三个常量,必须有且只有一个
O_RDONLY:只读模式
O_WRONLY:只写模式
O_RDWR:可读可写
以下的常量是选用的,这些选项是用来和上面的必选项进行按位或作为flags参数。
O_APPEND 表示追加,如果原来文件里面有内容,则这次写入会写在文件的最末尾。
O_CREAT 表示如果指定文件不存在,则创建这个文件,常与O_EXCL搭配使用
O_EXCL 表示如果要创建的文件已存在,则出错,同时返回 -1,并且修改 errno 的值。
O_TRUNC 表示截断,如果文件存在,并且以只写、读写方式打开,则将其长度截断为0,清空文件。
O_NOCTTY 如果路径名指向终端设备,不要把这个设备用作控制终端。
O_NONBLOCK 如果路径名指向 FIFO/块文件/字符文件,则把文件的打开和后继 I/O设置为非阻塞模式。
涉及到多进程,多线程访问,经常需要同步操作。以下三个常量同样是选用的,它们用于同步输入输出
O_DSYNC 等待物理 I/O 结束后再 write。在不影响读取新写入的数据的前提下,不等待文件属性更新。
O_RSYNC read 等待所有写入同一区域的写操作完成后再进行
O_SYNC同步IO方式写入文件,等待物理 I/O 结束后再 write,包括更新文件属性的 I/O。(强制刷新内核缓冲区到文件,多线程/多进程访问时,需要确保数据成功写入文件,才返回成功)

2.2 write函数

写文件函数

#include <unistd.h>

size_t write(int fd, const void *buf, size_t nbytes)

fd open得到的文件描述符
buf 需要写的数据
nbytes 需要写的数据长度

返回值:成功则返回已写的字节数,出错返回-1

写文件通常从文件的当前偏移量开始,如果指定了O_APPEND,则文件偏移量设置为结尾处。

文件偏移量:非负整数,代表文件当前操作位置相对文件开始处的偏移量,若未指定O_APPEND打开设备,文件偏移量默认在0字节处,若此时write5个字节,文件偏移量为5个字节。若指定O_APPEND,则打开文件后,文件偏移在文件的当前结尾处。
在这里插入图片描述

2.3 read函数

读文件函数

#include <unistd.h>

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

fd 文件描述符
buf 读取数据缓冲区
nbytes 读多少个字节

返回值:读到的字节数,若已到文件尾,则返回0.

2.4 lseek函数

设置指定文件偏移量

#include <unistd.h>
 
 off_t lseek(int fd, off_t offset, int whence);
 

fd 文件描述符
offsetwhence有关系
whence = SEEK_SET,则将文件偏移量设置文件开始处偏移offset个字节
whence = SEEK_CUR,则将文件偏移量设置为当前位置偏移offset个字节,可正可负。
whence = SEEK_END,则将文件偏移量设置为文件末尾长度偏移offset个字节,可正可负。

2.5 close函数

关闭文件

#include <unistd.h>

int close(int fd);

返回值:成功返回0,出错返回-1

注:进程终止时,内核还会自动关闭它所有的打开文件,所有有时候不会显示调用close

3、DEMO

根据运行可执行文件输入的第一个参数创建文件,写入数据后读取。

#include "stdio.h"
#include "unistd.h"
#include "fcntl.h"

int main(int argc, char **argv[])
{
    char write_buf[] = "hello world";
    char read_buf[1024] = {0};
    int ret = 0;
    int fd = 0;
    fd = open(argv[1], O_CREAT | O_RDWR | O_EXCL, 0777);
    if (fd < 0) {
        printf("Error opening\n");
        return -1;
    }
    printf("open succeeded, fd = %d\n", fd);

    ret = write(fd, write_buf, sizeof(write_buf));
    if (ret < 0) {
        printf("Error writing\n");
        return -1;
    }
    printf("write succeeded, ret = %d\n", ret);

    lseek(fd, 0, SEEK_SET); //改变文件偏移量到文件最开始处,若没有这句,文件偏移量指到文件末尾,无法读取到数据

    ret = read(fd, read_buf, sizeof(read_buf));
    if (ret < 0) {
        printf("Error read\n");
        return -1;
    }
    printf("read succeeded, read_buf = %s, ret:%d\n", read_buf, ret);

    close(fd);
    return 0;
}

运行结果
在这里插入图片描述

目前都是比较基础的API介绍,其中还会涉及到多线程/多进程访问,Linux缓冲区冲刷等知识点,后期有空再开一篇文章补充~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值