Linux c语言读写文件实例(C库和系统调用两种方式)

本文介绍了在Linux系统中使用C语言进行文件读写操作的两种方法:库函数(如fopen, fread, fwrite等)和系统调用(如open, read, write等)。通过代码实例展示了如何读取和写入文件,并讨论了两者之间的区别。在嵌入式系统中,理解并掌握这两种方式对于进行文件操作至关重要。" 112360573,10549086,Matlab无法识别USB相机:问题与解决,"['MATLAB', '图像采集', '硬件连接', '设备管理', '编程问题']


前言

在嵌入式系统上,经常会涉及到对文件进行读写的操作,本文主要介绍在Linux系统上常见的两种读写文件的方式,使用C语言库函数和系统调用。

一、使用C语言库函数的方式

1. 主要的相关函数接口

  1. fopen()
    打开文件, 第二个参数决定打开文件的mode, 具体的模式可以在Ubuntu上使用man 3 fopen命令查看细节
  2. fread()
    读文件里的内容,具体函数介绍可以在Ubuntu上使用man 3 fread命令查看
  3. fwrite()
    往文件里写数据,具体函数介绍可以在Ubuntu上使用man 3 fwrite命令查看
  4. fseek()
    可以移动文件头指针,具体函数介绍可以在Ubuntu上使用man 3 fseek命令查看
  5. ftell()
    计算文件大小,一般和fseek()组合使用,具体函数介绍可以在Ubuntu上使用man 3 ftell命令查看
  6. fclose()
    关闭文件,具体函数介绍可以在Ubuntu上使用man 3 fclose命令查看

2. 代码实例

以下代码实现的功能是从一张NV12格式的图片文件中读取它的Y分量数据存放到另一个文件中

#include <stdio.h>
#include <stdlib.h>


//src file src.yuv    1280*720*3/2 NV12
//dst file dst.y      1280*720     GREY

#define SRC_FILE "./src.yuv"
#define DST_FILE "./dst.y"

int main()
{
    int ret;

    FILE *src_fd;
    FILE *dst_fd;

    //--------------------------------------------------------src file
    

    //fopen src file
    src_fd = fopen(SRC_FILE, "r");                  //O_RDONLY mode
    if (!src_fd) {
        printf("fopen %s failed\n", SRC_FILE);
        return -1;
    }

    //get src file size
    if (fseek(src_fd, 0, SEEK_END) !=0) {          //将文件指针移动到文件末尾
        printf("fseek END error\n");
        return -1;
    }

    long size = ftell(src_fd);
    if (size == -1) {
        printf("get src file size failed\n");
        return -1;
    } else {
        printf("%s size is %ld\n", SRC_FILE, size);
    }

    //将文件指针返回到文件开始处
    if (fseek(src_fd, 0, SEEK_SET) != 0) {
        printf("fseek SET error");
        return -1;
    }
    
    long y_size = size * 2 / 3;

    //malloc memory 
    char *buffer = (char *)malloc(y_size);
    if (buffer == NULL) {
        printf("malloc memory failed\n");
        return -1;
    }

    //fread Y data of src file to buffer
    if (fread(buffer, 1, y_size, src_fd) != y_size) {
        printf("read Y data of src file failed\n");
        return -1;
    }

    //fclose src file
    fclose(src_fd);

    //--------------------------------------------------------dst file

    //fopen dst file
    dst_fd = fopen(DST_FILE, "w+");                      //RDWR mode 
    if (!dst_fd) {
        printf("fopen %s failed\n", DST_FILE);
        return -1;
    }

    //fwrite Y data to dst file
    if (fwrite(buffer, 1, y_size, dst_fd) != y_size) {
        printf("fwrite y_data to %s failed\n", DST_FILE);
        return -1;
    } else {
        printf("%s size is %ld\n", DST_FILE, y_size);
    }

    //fclose dst file
    fclose(dst_fd);
    
    return 0;
}

二、使用linux 系统调用相关接口的方式

1.主要的相关函数接口

  1. open()
    打开文件, 第二个参数决定打开文件的mode, 具体的模式可以在Ubuntu上使用man 2 open命令查看细节
  2. read()
    读文件里的内容, 第二个参数决定打开文件的mode, 具体的模式可以在Ubuntu上使用man 2 read命令查看细节
  3. write()
    往文件里写数据,具体函数介绍可以在Ubuntu上使用man 2 write命令查看
  4. close()
    关闭文件,具体函数介绍可以在Ubuntu上使用man 2 close命令查看

2. 代码实例

以下代码实现的功能是从一张NV12格式的图片文件中读取它的Y分量数据存放到另一个文件中

#include <stdio.h>
#include <stdlib.h>

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


//src file src.yuv    1280*720*3/2 NV12
//dst file dst.y      1280*720     GREY

#define SRC_FILE "./src.yuv"
#define DST_FILE "./dst.y"

int main()
{
    int ret;

    int src_fd, dst_fd;
    int y_size = 1280*720;

    // ----------------------------------------------src file

    //open src file
    src_fd = open(SRC_FILE, O_RDONLY);
    if (src_fd < 0) {
        printf("open %s failed\n", SRC_FILE);
        return -1;
    }

    //malloc memory
    char *buffer = (char *)malloc(y_size);
    if (buffer == NULL) {
        printf("malloc memory failed\n");
        return -1;
    }

    //read Y data of src file to buffer
    ret = read(src_fd, buffer, y_size);
    if (ret < 0) {
        printf("read Y data of %s to buffer failed\n", SRC_FILE);
        return -1;
    }

    close(src_fd);

    // ----------------------------------------------dst file

    //open dstfile
    dst_fd = open(DST_FILE, O_RDWR | O_CREAT);
    if (dst_fd < 0) {
        printf("open %s failed\n", DST_FILE);
        return -1;
    }

    //write Y data from buffer to dst file
    ret = write(dst_fd, buffer, y_size);
    if (ret < 0) {
        printf("write Y data from buffer to %s failed\n", DST_FILE);
        return -1;
    }

    close(dst_fd);

    return 0;
}

三、以上两种方式的区别

  1. open是unix系统调用函数,返回的是文件描述符;而fopen是ANSIC标准中的C语言库函数,在不同的系统中应该调不同的内核api,返回的是一个指向文件结构的指针;
  2. 在linux 系统中 系统调用相关的接口是比较底层的接口,fopen等c语言库函数是比较上层的接口, 并且fopen等c语言库函数最终都会向下调用到系统调用相关的接口,因此使用系统调用相关接口的方式效率是比使用fopen等c语言库函数接口的方式要高;

总结

在嵌入式系统上经常会遇到需要读写文件的场景,比如图像处理,如果没有摄像头,我们就可以用文件来作为输入源,这就需要将文件中的数据读到内存中,然后图像处理的结果,可以保存为文件,这就需要将内存中的数据写到文件里面,因此掌握读写文件的相关函数接口非常重要。

参考资料

  1. https://blog.csdn.net/ypshowm/article/details/90752521
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值