首页 > 系统相关 >重头开始嵌入式第十八天(Linux系统编程 文件IO)

重头开始嵌入式第十八天(Linux系统编程 文件IO)

时间:2024-08-12 18:27:59浏览次数:14  
标签:fp 第十八天 FILE 文件 函数 写入 IO Linux 读取

Linux系统编程内容

Linux 系统编程涵盖了众多方面的知识和技术:
 
1. 文件 I/O 操作:包括打开、读取、写入、关闭文件,以及处理文件的权限、属性等。
2. 进程管理:创建新进程、进程的终止、等待进程结束、进程的执行状态控制等。
3. 信号处理:接收和处理系统发送的各种信号,以响应特定的事件。
4. 线程编程:创建、同步和管理线程,实现多线程并发执行。
5. 进程间通信(IPC):如管道、消息队列、共享内存、信号量等方式,实现不同进程之间的数据交换和协调工作。
6. 套接字编程:用于网络通信,实现客户端与服务器之间的数据传输。
7. 系统调用和库函数:熟练使用 Linux 提供的系统调用和相关的库函数来完成各种任务。
8. 内存管理:包括动态内存分配(如 malloc 和 free )以及对内存映射文件的操作。
 
这些是 Linux 系统编程的核心内容,通过学习和实践这些方面,可以开发出高效、稳定的 Linux 应用程序。从今天开始就正式进入系统编程内容了

文件IO

1. 标准IO的概念

标准输入输出(I/O)是与计算机程序交互的基本方式。ISO C标准提供了一套标准的输入输出库,使程序能够方便地处理输入输出操作。

- **输入(I)**:在C语言中,通常情况下,标准输入设备是键盘。程序默认从键盘读取数据。Linux中,标准输入对应的设备为`/dev/input`。
  
- **输出(O)**:标准输出设备通常是显示器,程序默认将结果输出到屏幕。

在Linux操作系统中,I/O操作都是围绕文件进行的。标准I/O库是对文件I/O的封装,使得任何支持C语言的系统都能通用地处理文件存储。

标准I/O操作通常是针对普通文件的,它采用了缓冲机制。缓冲区位于文件I/O与用户程序之间,这种设计可以有效减少系统调用的次数,从而提高效率并节省IO调度资源。

2. 文件的概念及作用

在Linux及Unix-like操作系统中,一切皆文件。文件不仅存储数据,还可以存储指令和配置。在这种模型中,文件可以分为几种类型:

- **普通文件**:用于存储数据,比如文本文件和二进制文件。
- **目录文件**:用于组织文件系统中的其他文件。
- **设备文件**:用于与硬件设备交互,比如硬盘、打印机等。
  
文件在操作系统中扮演了重要的角色:

- **数据持久化**:文件可存储重要数据和状态,使其在程序结束后不丢失。
- **信息共享**:不同程序可以通过文件共享数据。
- **配置管理**:许多程序使用配置文件来设定选项和参数,便于用户调整行为。

通过标准I/O操作,程序可以方便地读写各种类型的文件,实现更复杂的数据处理和交互功能。

在Linux中,文件的类型有以下7种:

  1. "d" - 目录文件(directory file)
  2. "-" - 普通文件(regular file)
  3. "l" - 符号链接文件(symbolic link file)
  4. "p" - 命名管道文件(named pipe file)
  5. "s" - 套接字文件(socket file)
  6. "c" - 字符设备文件(character device file)
  7. "b" - 块设备文件(block device file)

其中,d表示目录文件,-表示普通文件,l表示符号链接文件,p表示命名管道文件,s表示套接字文件,c表示字符设备文件,b表示块设备文件。

关于IO的分类,有以下几种:

  1. 标准IO(Standard IO):ANSI C设计的一组用文件IO封装的操作库函数,通过头文件stdio.h进行操作。
  2. 文件IO(File IO):底层软件的系统调用,用于对文件进行读写操作。
  3. ASCII码数据流:以ASCII码作为数据流的文本流。
  4. 二进制数据流:以二进制数据作为数据流的二进制流。

文件流是通过FILE结构定义的对象,用FILE指针来表示。文件流可以理解为数据从文件中流入和流出所体现出来的字节流,它由文件的头部和尾部组成。

在Linux中,可以使用man命令来查看有关命令、系统调用函数和标准库函数的帮助信息。man命令后面跟着的数字表示查看的是哪个部分的帮助信息,例如man 1 xxx表示查看命令xxx的帮助信息,man 2 xxx表示查看系统调用函数xxx的帮助信息,man 3 xxx表示查看标准库函数xxx的帮助信息。

对于文件IO相关的标准库函数,可以使用stdio.h头文件来使用,该头文件位于/usr/include/stdio.h。标准库函数分为系统库函数和用户自定义函数,系统库函数的默认路径是/usr/include/,而用户自定义函数的默认路径是当前路径。例如,可以使用printf、scanf、getc等函数来进行标准输入输出的操作。

文件内容可以分为文本文件和二进制文件。文本文件是以ASCII码数据流的形式存储的文件,而二进制文件是以二进制数据流的形式存储的文件。

3.文件流(File stream)

文件流(File stream)是指将文件的读写操作视为数据流的形式。在编程中,文件流可以用于读取和写入文件中的数据。

文件流有两种类型:输入流和输出流。输入流用于从文件中读取数据,输出流用于向文件中写入数据。

使用文件流进行文件读写的过程如下:

1. 打开文件流:使用相应的编程语言提供的函数或方法,打开要读取或写入的文件,并创建文件流对象。

2. 读取或写入数据:使用文件流对象的读取或写入方法,进行数据的读取或写入操作。读取操作会从文件中读取一定数量的数据,写入操作会将指定的数据写入文件。

3. 关闭文件流:使用相应的编程语言提供的函数或方法,关闭文件流并释放相关资源。

文件流的优点是可以按照流的方式读取或写入文件,适合处理大文件或需要逐行读取的场景。文件流也可以按字节进行读写,适合处理二进制文件。

文件流在编程中广泛应用于文件读写、日志记录、数据备份等场景。常用的编程语言如C、C++、Java、Python等都提供了对文件流的支持。

4.相关函数

fopen

在 C 语言中, fopen  函数用于打开文件。

其函数原型为:

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

-  filename :要打开的文件名(包括路径)。

-  mode :指定打开文件的模式,常见的模式有:

-  "r" :以只读方式打开文件,如果文件不存在则打开失败。

-  "w" :以只写方式打开文件,如果文件不存在则创建,如果存在则清空文件内容。

-  "a" :以追加方式打开文件,如果文件不存在则创建,写入的数据会添加到文件末尾。

-  "r+" :以读写方式打开文件,文件必须存在。

-  "w+" :以读写方式打开文件,如果文件不存在则创建,如果存在则清空文件内容。

-  "a+" :以读和追加方式打开文件,如果文件不存在则创建。

 fopen  函数成功打开文件时返回一个  FILE  类型的指针,该指针用于后续对文件的读写操作。如果打开文件失败,则返回  NULL  。

在使用  fopen  后,务必在操作完成后使用  fclose  函数关闭文件,以释放相关资源。

例如:

#include <stdio.h>



int main() {

    FILE *fp;

    fp = fopen("example.txt", "w");

    if (fp == NULL) {

        printf("无法打开文件\n");

        return 1;

    }

    // 在这里进行文件写入操作

    fclose(fp);

    return 0;

}



fclose

在 C 语言中, fclose  函数用于关闭一个之前通过  fopen  函数打开的文件。

其函数原型为:

int fclose(FILE *stream);

 stream  是指向要关闭的文件的  FILE  指针。

 fclose  函数执行以下重要操作:

1. 刷新输出缓冲区中的数据,确保所有未写入的数据都被实际写入到文件中。

2. 释放与该文件相关的系统资源。

 fclose  函数返回 0 表示成功关闭文件,返回  EOF (通常定义为 -1)表示关闭文件时发生错误。

例如:

#include <stdio.h>



int main() {

    FILE *fp = fopen("test.txt", "w");

    if (fp == NULL) {

        printf("无法打开文件\n");

        return 1;

    }

    // 写入一些数据

    fprintf(fp, "这是一些测试数据");

    // 关闭文件

    if (fclose(fp) == EOF) {

        printf("关闭文件时出错\n");

        return 1;

    }

    return 0;

}

fgetc

在 C 语言中, fgetc  函数用于从指定的文件流中读取一个字符。
 
其函数原型为:

int fgetc(FILE *stream);


 stream  是指向要读取的文件流的  FILE  指针。
 
 fgetc  函数从文件流中读取下一个字符,并将其作为  unsigned char  类型的值转换为  int  类型后返回。如果到达文件末尾或发生读取错误,它将返回  EOF (通常定义为 -1)。
 
以下是一个简单的示例,展示如何使用  fgetc  函数读取文件中的字符:

#include <stdio.h>

int main() {
    FILE *fp;
    char ch;

    fp = fopen("example.txt", "r");
    if (fp == NULL) {
        printf("无法打开文件\n");
        return 1;
    }

    while ((ch = fgetc(fp))!= EOF) {
        putchar(ch);
    }

    fclose(fp);

    return 0;
}


在这个示例中,不断使用  fgetc  函数读取文件中的字符,并通过  putchar  函数输出到屏幕上,直到遇到文件末尾。
 

fputc

在 C 语言中, fputc  函数用于将一个字符写入到指定的文件流中。
 
其函数原型为:

int fputc(int c, FILE *stream);


 c  是要写入的字符(以  int  类型传递,实际存储的是字符的 ASCII 值)。 stream  是指向目标文件流的  FILE  指针。
 
 fputc  函数返回写入的字符,如果发生错误则返回  EOF  。
 
以下是一个使用  fputc  函数向文件写入字符的示例:

#include <stdio.h>

int main() {
    FILE *fp;

    fp = fopen("output.txt", "w");
    if (fp == NULL) {
        printf("无法打开文件\n");
        return 1;
    }

    fputc('H', fp);
    fputc('e', fp);
    fputc('l', fp);
    fputc('l', fp);
    fputc('o', fp);

    fclose(fp);

    return 0;
}


 
在这个示例中,依次向文件 "output.txt" 写入了字符 'H'、'e'、'l'、'l'、'o' 。
 
 

fgets

在 C 语言中, fgets  函数用于从指定的文件流中读取一行字符串。

其函数原型为:

char *fgets(char *str, int n, FILE *stream);

-  str  :指向用来存储读取字符串的字符数组。

-  n  :指定读取的最大字符数(包括最后的  '\0'  字符)。

-  stream  :指向要读取的文件流。

 fgets  函数从文件流中读取最多  n - 1  个字符,并在读取的字符串末尾添加  '\0'  作为字符串结束标志。如果在达到  n - 1  个字符之前遇到换行符  '\n'  或文件结束标志,读取操作也会停止。

如果成功读取到字符串(包括读到空行), fgets  函数返回  str  ;如果遇到文件结束或发生错误,则返回  NULL  。

以下是一个示例代码:

#include <stdio.h>



int main() {

    FILE *fp;

    char str[100];



    fp = fopen("example.txt", "r");

    if (fp == NULL) {

        printf("无法打开文件\n");

        return 1;

    }



    if (fgets(str, sizeof(str), fp)!= NULL) {

        printf("%s", str);

    }



    fclose(fp);



    return 0;

}

fputs

在 C 语言中, fputs  函数用于将一个字符串写入到指定的文件流中。

其函数原型为:

int fputs(const char *str, FILE *stream);

-  str  :要写入的字符串。

-  stream  :指向目标文件流的  FILE  指针。

 fputs  函数将字符串  str  写入到指定的文件流中,但它不会自动添加换行符。如果写入成功,函数返回一个非负值;如果发生错误,则返回  EOF  。

以下是一个简单的示例:

#include <stdio.h>



int main() {

    FILE *fp;



    fp = fopen("output.txt", "w");

    if (fp == NULL) {

        printf("无法打开文件\n");

        return 1;

    }



    fputs("这是写入的字符串", fp);



    fclose(fp);



    return 0;

}

fwrite

在 C 语言中, fwrite  函数用于将数据块写入到指定的文件流中。

其函数原型为:

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

-  ptr :指向要写入数据的指针。

-  size :每个数据项的大小(以字节为单位)。

-  nmemb :要写入的数据项的数量。

-  stream :指向目标文件流的  FILE  指针。

 fwrite  函数返回实际写入的数据项的数量。如果返回值小于  nmemb  ,则表示发生了错误。

以下是一个示例代码,展示如何使用  fwrite  函数写入数据:

#include <stdio.h>



int main() {

    FILE *fp;

    int data[] = {1, 2, 3, 4, 5};



    fp = fopen("data.bin", "wb");

    if (fp == NULL) {

        printf("无法打开文件\n");

        return 1;

    }



    size_t written = fwrite(data, sizeof(int), sizeof(data) / sizeof(int), fp);



    if (written!= sizeof(data) / sizeof(int)) {

        printf("写入错误\n");

    }



    fclose(fp);



    return 0;

}



在这个示例中,将一个整数数组写入到二进制文件中。

fread

在 C 语言中, fread  函数用于从指定的文件流中读取数据块。

其函数原型为:

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

-  ptr :指向用于存储读取数据的内存缓冲区的指针。

-  size :每个数据项的大小(以字节为单位)。

-  nmemb :要读取的数据项的数量。

-  stream :指向要读取的文件流的  FILE  指针。

 fread  函数返回实际读取到的数据项的数量。如果返回值小于  nmemb  ,可能表示到达了文件末尾或者发生了错误。

以下是一个简单的示例,展示如何使用  fread  函数读取数据:

#include <stdio.h>



int main() {

    FILE *fp;

    int data[5];



    fp = fopen("data.bin", "rb");

    if (fp == NULL) {

        printf("无法打开文件\n");

        return 1;

    }



    size_t read = fread(data, sizeof(int), 5, fp);



    if (read!= 5) {

        printf("读取错误或未读取到完整数据\n");

    }



    fclose(fp);



    // 打印读取到的数据

    for (int i = 0; i < 5; i++) {

        printf("%d ", data[i]);

    }

    printf("\n");



    return 0;

}

标签:fp,第十八天,FILE,文件,函数,写入,IO,Linux,读取
From: https://blog.csdn.net/qq_64792908/article/details/141134315

相关文章

  • 【嵌入式linux开发】旭日x3派部署自己训练的yolov5模型(安全帽识别、视频流推理、yolov
    旭日x3派部署自己训练的模型(安全帽识别、视频流推理、yolov5-6.2)windows,框架pytorch,python3.7效果模型训练模型转换1、pt模型文件转onnx2、检查onnx模型3、准备校准数据4、onnx转bin上板视频流推理1、图片推理2、视频流推理效果模型训练进官网可克隆yolov5......
  • Linux系统计划任务
    Linux系统计划任务什么是计划任务,计划任务类似于我们平时⽣活中的闹钟。在Linux系统的计划任务服务crond可以满⾜周期性执⾏任务的需求。crond进程每分钟会处理⼀次计划任务,计划任务主要是做⼀些周期性的任务⽬前最主要的⽤途是定时备份数据计划任务分为以下两种情况:1......
  • linux中mysql开启远程ssh连接
    步骤1:配置MySQL允许远程连接1.1修改MySQL配置文件首先,你需要修改MySQL的配置文件(my.cnf或mysqld.cnf),以允许MySQL监听所有网络接口,而不仅仅是本地主机。打开MySQL的配置文件,通常在/etc/mysql/my.cnf或/etc/mysql/mysql.conf.d/mysqld.cnf,或者在CentOS/RHEL......
  • 在clion IDE中编写ADI CCES的工程代码,cmake设置
    有时需要在CCES中编译代码,或者在stm32的mdk或者stm32cubeide中编译,但是习惯了在clion中编写代码,但是clion中需要CMAKES设置,所以需要自己写一个cmake文件,下面是一个模板文件cmake_minimum_required(VERSION3.24)project(proj_name)#add_definitions(-DCORE0-D_DEBUG-DAD......
  • 解决阿里云CLB的健康检查后业务日志中出现“Connection reset by peer”的错误
    目录起因排查过程问题原因解决方案方案一:更换监听类型(TCP→HTTP/HTTPS)方案二:日志过滤方案三:关闭日志级别info推荐方案起因环境:阿里专有云平台今天发现nginx日志中频繁出现类似Connectionresetbypeer的网络连接错误排查过程起初怀疑是Nginx配置问题,但检查后确认配置正......
  • ProTable rowSelection 支持多选
    前言:第一次用到多选,gpt非常好用,比之前网页方便太多。 importProTablefrom'@ant-design/pro-table';importReact,{useState}from'react';constTableWithRowSelection=()=>{//使用useState钩子来保存选中的行const[selectedRows,setSelectedRows]......
  • 修改『Visual Studio Code(VS Code)』插件默认安装路径的方法
    前言作者希望将『VisualStudioCode(以下简称为“VSCode”)』的插件安装在数据盘(D盘),用于统一管理,因此需要修改VSCode插件安装路径。VSCode插件默认的安装位置为:C:\Users\{个人用户名}\.vscode\extensions。方法一:修改快捷方式目标路径(★★☆)1.确保『code』快捷命令的可用......
  • Visual Studio 修改NuGet 包路径
    目的:通过NuGet安装包时,NuGet先将包下载至一个统一的目录,默认路径是:C:\Users\{用户名}\.nuget\packages。现在需要将其迁移到目录E:\nuget\packages步骤1、在C:\ProgramFiles(x86)\NuGet\Config目录中找到Microsoft.VisualStudio.Offline.config。在文件末尾添加一......
  • Linux操作系统云主机中buffer和cache占用内存怎么办?
    问题描述系统长期运行后,free命令查看系统内存,发现剩余内存不足,大部分是buffer和cache。问题分析在Linux的内存管理中,buffer是Linux内存中的Buffercache。cache是Linux内存中的Pagecache。Buffercache:主要是当系统对块设备进行读写的时候,对块进行数据缓存的系统来使用,即......
  • Linux中套接字可读|可写--SO_RCVLOWAT和SO_SNDLOWAT
    目录SO_RCVLOWAT(接收低水位标记)SO_SNDLOWAT(发送低水位标记)注意事项在GNULinux中,SO_RCVLOWAT和SO_SNDLOWAT是用于设置套接字选项的两个标志,分别用于设置接收和发送低水位标记。这些选项可以帮助应用程序控制网络通信的流量控制。SO_RCVLOWAT(接收低水位标记)......