【IO操作】标准IO和文件IO

news2024/12/23 20:42:11

一.标准IO和文件IO的区别

(1)一般标准IO指的是C语言的IO操作,文件IO一般指的是Linux系统调用的IO操作。标准O因为是C语言提供的标准库,所以可以在其他操作系统平台编译后可以执行,但是文件IO只能在Linux下使用,标准IO意味着可以在多个平台移植使用。

(2)Linux的IO操作是基于文件描述符的。文件描述符是一个非负整数,用于标识打开或创建的文件。Linux提供了几个系统调用函数来进行IO操作,如open、read、write、close等。

文件的打开通过open函数完成,它返回一个文件描述符。读取文件内容使用read函数,它接受文件描述符、缓冲区地址和读取字节数作为参数,并返回实际读取的字节数。写入文件内容使用write函数,它接受文件描述符、缓冲区地址和写入字节数作为参数,并返回实际写入的字节数。关闭文件使用close函数,它接受文件描述符作为参数。

(3)C语言的IO操作是基于文件指针的。文件指针是一个指向FILE结构体的指针,该结构体描述了文件的属性和缓冲区等信息。C语言提供了一些库函数来进行IO操作,如fopen、fread、fwrite、fclose等。

文件的打开通过fopen函数完成,它返回一个文件指针。读取文件内容使用fread函数,它接受文件指针、缓冲区地址、每个元素的大小和读取元素的个数作为参数,并返回实际读取的元素个数。写入文件内容使用fwrite函数,它接受文件指针、缓冲区地址、每个元素的大小和写入元素的个数作为参数,并返回实际写入的元素个数。关闭文件使用fclose函数,它接受文件指针作为参数。

(4)标准IO和文件IO都可以用来访问文件,那么他们之间有什么区别呢?

通过文件IO读写文件时,每次操作都会执行相关系统调用。这样处理的好处是可以直接读写实际文件,坏处是频繁地系统调用会增加系统开销;而标准IO可以看做是在文件IO的基础上封装了缓冲机制,先读写缓冲区,必要时再访问实际文件,从而减少系统调用次数。

文件IO中用文件描述符表示一个打开的文件,可以访问不同类型的文件(如普通文件、设备文件和管道文件)。而标准IO中用FILE(流)表示一个打开的文件,通常只用来访问普通文件

总的来说,Linux的IO操作是底层的系统调用函数,而C语言的IO操作是基于库函数的高层封装。两者都可以用来进行文件的读写操作,但使用的方式和函数有所不同。

二.标准IO

标准IO库提供了一系列函数,用于对标准输入、输出、错误流以及文件进行操作。这些函数通常在 <stdio.h> 头文件中声明。下面是一些常用的标准IO函数以及它们的功能:

  1. fopen() 函数

    #include <stdio.h> FILE *fopen(const char *pathname, const char *mode);

    参数:
       pathname:文件路径名。
       mode:文件打开模式,可以取以下值:
          "r":只读模式打开文件。
          "w":只写模式打开文件,如果文件不存在则创建文件,如果文件已存在则清空文件。
          "a":追加模式打开文件,如果文件不存在则创建文件。
          "r+":读写模式打开文件。
          "w+":读写模式打开文件,如果文件不存在则创建文件,如果文件已存在则清空文件。
          "a+":读写模式打开文件,如果文件不存在则创建文件,并在文件末尾追加数据。
    更多模式可以查阅相关文档。
    返回值:返回一个文件指针(FILE *),用于后续的文件操作。如果打开文件失败,返回 NULL,并设置 errno 来指示错误原因。
    常见用法:用于打开文件,获取文件指针,以便后续的文件操作。

  2. fclose() 函数

    #include <stdio.h> 
    int fclose(FILE *stream);
    参数:
       stream:文件指针,需要关闭的文件。
    返回值:返回 0 表示成功关闭文件,返回 EOF 表示失败,并设置 errno 来指示错误原因。
    常见用法:用于关闭一个已经打开的文件。
    
  3. fread() 函数

    #include <stdio.h> size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

    参数:
       ptr:指向存储读取数据的缓冲区。
       size:每个数据项的大小(以字节为单位)。
       nmemb:要读取的数据项的数量。
       stream:文件指针,指向要读取数据的文件。
    返回值:返回实际读取的数据项数量,如果到达文件末尾或出错返回值小于 nmemb,同时设置 errno 来指示错误原因。
    常见用法:用于从文件中读取数据。

  4. fwrite() 函数

    #include <stdio.h> size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

    参数:
        ptr:指向要写入数据的缓冲区。
       size:每个数据项的大小(以字节为单位)。
       nmemb:要写入的数据项的数量。
       stream:文件指针,指向要写入数据的文件。
    返回值:返回实际写入的数据项数量,如果出错返回值小于 nmemb,同时设置 errno 来指示错误原因。
    常见用法:用于向文件中写入数据。

  5. fseek() 函数

    #include <stdio.h> 
    int fseek(FILE *stream, long offset, int whence);
    参数:
       stream:文件指针,指向要定位的文件。
       offset:偏移量。
          whence:偏移起始位置,可以取以下值:
          SEEK_SET:文件开头。
          SEEK_CUR:当前文件位置。
          SEEK_END:文件末尾。
    返回值:返回 0 表示成功,返回非 0 表示失败,并设置 errno 来指示错误原因。
    常见用法:用于在文件中移动文件指针。
    

 

#include <stdio.h>

int main() 
{
    FILE *fp;
    char buffer[100];

    // 打开一个文件来写入数据
    fp = fopen("example.txt", "w");
    if (fp == NULL) 
	{
        printf("无法打开文件\n");
        return 1;
    }
    fprintf(fp, "这是一个用于示例的文件\n");
    fclose(fp);

    // 打开文件来读取数据
    fp = fopen("example.txt", "r");
    if (fp == NULL) 
	{
        printf("无法打开文件\n");
        return 1;
    }
    fgets(buffer, 100, fp);
    printf("读取的内容: %s", buffer);
    fclose(fp);

    return 0;
}

 执行结果:

这是一个用于示例的文件

三.文件IO 

在Linux系统中,文件I/O操作通常使用系统调用来实现。下面是一些常见的Linux文件I/O系统调用以及它们的功能:

好的,我会重新整理一下,详细说明每个函数的参数、返回值以及常见用法:

  1. open() 函数

    #include <fcntl.h> 
    int open(const char *pathname, int flags, mode_t mode);
    参数:
       pathname:文件路径名。
       flags:文件打开标志,可以取以下值的组合:
          O_RDONLY:只读模式打开文件。
          O_WRONLY:只写模式打开文件。
          O_RDWR:读写模式打开文件。
          O_CREAT:如果文件不存在,则创建文件。
          O_TRUNC:如果文件存在且为只写或读写打开,则将文件长度截断为 0,即清空文件内      容。
          O_APPEND:在文件末尾追加数据。
          等等,还有其他的标志,可根据需要组合使用。
       mode:文件权限,仅在 O_CREAT 标志被设置时有效,通常为八进制数。
    返回值:返回一个新的文件描述符(非负整数),如果打开文件失败,返回 -1,并设置 errno 来指示错误原因。
    
    常见用法:用于打开文件,获取文件描述符,以便后续的文件操作。
  2. close() 函数

    #include <unistd.h> 
    int close(int fd);
    参数:
       fd:文件描述符,需要关闭的文件。
    返回值:返回 0 表示成功关闭文件,返回 -1 表示失败,并设置 errno 来指示错误原因。
    
    常见用法:用于关闭一个已经打开的文件。
  3. read() 函数

    #include <unistd.h> 
    ssize_t read(int fd, void *buf, size_t count);
    参数:
       fd:文件描述符。
       buf:用于存放读取数据的缓冲区。
       count:要读取的字节数。
    返回值:返回实际读取的字节数,如果到达文件末尾返回 0,出错返回 -1,并设置 errno 来指示错误原因。
    
    常见用法:用于从文件中读取数据。
  4. write() 函数

    #include <unistd.h> ssize_t write(int fd, const void *buf, size_t count);

    • 参数:

      • fd:文件描述符。
      • buf:要写入的数据。
      • count:要写入的字节数。
    • 返回值:返回实际写入的字节数,出错返回 -1,并设置 errno 来指示错误原因。

    • 常见用法:用于向文件中写入数据。

  5. lseek() 函数

    #include <unistd.h> 
    off_t lseek(int fd, off_t offset, int whence);
    参数:
       fd:文件描述符。
       offset:偏移量。
          whence:偏移起始位置,可以取以下值:
          SEEK_SET:文件开头。
          SEEK_CUR:当前文件位置。
          SEEK_END:文件末尾。
    返回值:返回新的文件偏移量(以字节为单位),出错返回 -1,并设置 errno 来指示错误原因。
    
    常见用法:用于在文件中移动文件指针。
  6. fcntl() 函数

    #include <fcntl.h>
    int fcntl(int fd, int cmd, ... /* arg */ );

    参数:
         fd:文件描述符。
         cmd:操作指令,可以取以下值:

                  F_SETFD:设置文件描述符标志。

                  F_GETFD:获取文件描述符标志。

                  F_SETFL:设置文件状态标志。

                  F_GETFL:获取文件状态标志。

                 F_DUPFD:复制文件描述符。

    返回值:根据操作指令的不同有不同的含义,出错返回 -1,并设置 errno 来指示错误原因。

    常见用法:用于对文件描述符进行各种控制操作,如设置文件状态标志、获取文件状态标志等。


    如果 cmd 参数需要额外的参数,则需要将其作为可变参数传递给 fcntl() 函数。

    等等,还有其他的操作指令,具体可以查阅相关文档

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#define BUFFER_SIZE 1024

int main() {
    int fd;
    char buffer_write[BUFFER_SIZE];
    char buffer_read[BUFFER_SIZE];
    ssize_t bytes_read;

    // 创建一个示例文件并写入内容
    fd = open("example.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd == -1) 
	{
        perror("无法创建文件");
        return 1;
    }
	strcpy(buffer_write,"这是一个示例文件");
    write(fd, buffer_write, strlen(buffer_write));
    close(fd);

    // 打开文件来读取数据
    fd = open("example.txt", O_RDONLY);
    if (fd == -1) 
	{
        perror("无法打开文件");
        return 1;
    }

    // 逐步读取文件内容
    while ((bytes_read = read(fd, buffer_read, BUFFER_SIZE)) > 0) 
	{
        write(STDOUT_FILENO, buffer_read, bytes_read); // 将读取的内容直接写入标准输出
    }
    if (bytes_read == -1) 
	{
        perror("读取文件失败");
        close(fd);
        return 1;
    }
    
    // 关闭文件
    close(fd);

    return 0;
}

 执行结果:

这是一个示例文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1639118.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言高效学习、提升方法

前言 已经用了十多年的C语言&#xff0c;回头看怎么学习、提升最快呢&#xff1f;个人觉得还是要从框架上去着手学习&#xff0c;用全局眼光去看、去学&#xff0c;主要是三部分&#xff1a;关键字及基本语法、重点功能点及标准库函数&#xff1b;只要把这三部分基本搞懂了&am…

AD | Altium Designer(原理图设计、电路仿真、PCB绘图)汉化版

Altium Designer(原理图设计、电路仿真、PCB绘图) 通知公告 Altium Designer(AD)是一种功能强大的电子设计自动化(EDA)软件。它主要用于设计和开发电子产品,如电路板(PCB)、集成电路(IC)和嵌入式系统。AD提供了完整的设计工具套件,包括原理图设计、PCB布局、仿真、设…

蓝桥杯单片机省赛——第八届“基于单片机的电子钟程序设计与调试”程序部分

往期回顾 第三届蓝桥杯单片机省赛 第四届蓝桥杯单片机省赛 第五届蓝桥杯单片机省赛 第六届蓝桥杯单片机省赛 第七届蓝桥杯单片机省赛 文章目录 往期回顾一、前期准备二、代码详情1.基础代码蜂鸣器/继电器/led/定时器之类的代码 2.按键详解按键写法讲解 3.驱动的处理驱动写法讲…

【前端篇】微信小程序ActionSheet封装 -- 封装特性,开发只需要关注功能

大家好啊&#xff0c;这次来分享一下小程序开发的一个使用封装。 背景 先来看下什么是ActionSheet&#xff0c;参考下图&#xff08;来源&#xff1a;豆流便签&#xff09; 参考原生代码实现&#xff1a; wx.showActionSheet({itemList: ["action1", "actio…

万万没想到,延缓帕金森病进展的“玄机”竟然就在腿上?【北京仁爱堂】

帕金森病患者的腿部变化&#xff0c;其实可以反应出很多问题。例如行走的变化问题、步态的异常等问题&#xff0c;可以反应病情轻重程度。而通过保持腿部肌肉活动的状态&#xff0c;也可以使帕金森病的症状得到一定的缓解&#xff0c;甚至有助于防止病情恶化。 帕金森病腿部变…

C++类和对象上篇

&#x1f407; &#x1f525;博客主页&#xff1a; 云曦 &#x1f4cb;系列专栏&#xff1a;[C] &#x1f4a8;路漫漫其修远兮 吾将而求索 &#x1f49b; 感谢大家&#x1f44d;点赞 &#x1f60b;关注&#x1f4dd;评论 文章目录 &#x1f4d9;前言&#x1f4d9;1、面向过程…

Java创建并遍历N叉树(前序遍历)

力扣 title589&#xff1a;N叉树的前序遍历 给定一个 n 叉树的根节点 root &#xff0c;返回 其节点值的 前序遍历 。 n 叉树 在输入中按层序遍历进行序列化表示&#xff0c;每组子节点由空值 null 分隔&#xff08;请参见示例&#xff09;。 思路&#xff1a; 1.初始化时…

C++_set和map的学习

1. 关联式容器 STL中的容器有序列式容器和关联式容器。 其中 vector 、 list 、 deque 、 forward_list(C11)就是序列式容器&#xff0c; 因为其底层为线性序列的数据结构&#xff0c;里面 存储的是元素本身 关联式容器 也是用来存储数据的&#xff0c;与序列式容器不同的是&am…

企业办公网络安全为何每个企业都要重视

随着互联网的持续发展&#xff0c;当前大量企业通过网络将集团总部与各分公司/厂区结合起来&#xff0c;便捷的沟通和共享方式大大提高了企业的生产力和工作效率&#xff0c;如何能够保障一个稳定、安全、便捷的整体网络成为企业IT建设的重要课题。对大量企业用户进行调研后发现…

万界星空科技商业开源MES+项目合作+商业开源低代码平台

今天我想和大家分享的是一套商业开源的 MES制造执行管理系统带源码。对于制造业而言&#xff0c;MES 是一个至关重要的系统&#xff0c;它可以帮助企业提高生产效率、优化资源利用、提高产品质量&#xff0c;从而增强市场竞争力。 什么是 MES&#xff1f; MES 是指通过计算机技…

llama-factory/peft微调千问1.5-7b-chat

目标 使用COIG-CQIA数据集和通用sft数据集对qwen1.5-7b-chat进行sft微调,使用公开dpo数据集进行dpo对齐。学习千问的长度外推方法。 一、训练配置 使用Lora方式, 将lora改为full即可使用全量微调。 具体的参数在 该框架将各个参数、训练配置都封装好了,直接使用脚本,将数…

unity项目《样板间展示》开发:菜单界面

unity项目《样板间展示》开发&#xff1a;菜单界面 前言UI菜单创建逻辑实现结语 前言 这是这个项目demo教程的最后一节&#xff0c;这节是菜单界面部分的创建 UI菜单创建 创建一个新的场景&#xff0c;在Scene文件中右键选择Create->Scene&#xff0c;创建新的场景 在场景…

【Linux】创建/扩容swap交换空间swap优化

一、当前交换空间大小 目前交换空间大小为2G 二、创建swap交换空间 #创建大小为2G的交换空间 [roothadoop01 data1]# dd if/dev/zero of/data1/swapfile bs1M count2048 #将文件设置为交换空间 [roothadoop01 data1]# mkswap /data1/swapfile #启用交换空间 [roothadoop01 da…

ElasticSearch教程入门到精通——第一部分(基于ELK技术栈elasticsearch 8.x新特性)

ElasticSearch教程入门到精通——第一部分&#xff08;基于ELK技术栈elasticsearch 8.x新特性&#xff09; 1. ElasticSearch安装&#xff08;略&#xff09;2. ElasticSearch基础功能2.1 索引操作2.1.1 创建索引2.1.2 Head 索引2.1.3 查询索引2.1.3.1 查询单独索引2.1.3.2 查询…

智能产品信息模型-控制信息模型

数字化的核心是数字化建模&#xff0c;为一个事物构建数字模型是一项十分复杂的工作。不同的应用场景&#xff0c;对事物的关注重点的不同的。例如&#xff0c;对于一个智能传感器而言&#xff0c;从商业的角度看&#xff0c;产品的信息模型中应该包括产品的类型&#xff0c;名…

Vue 组件的三大组成部分

Vue 组件通常由三大组成部分构成&#xff1a;模板&#xff08;Template&#xff09;、脚本&#xff08;Script&#xff09;、样式&#xff08;Style&#xff09; 模板部分是组件的 HTML 结构&#xff0c;它定义了组件的外观和布局。Vue 使用基于 HTML 的模板语法来声明组件的模…

如何维持CISSP证书:附免费获取CPE学分的16个官方渠道

CISSP 证书只有三年有效期&#xff08;如2023.11-2026.10&#xff09;&#xff0c;需要每年维护才能续证。持证者需要持续获取 CPE 学分来维持证书&#xff0c;否则证书到期后将失效。本文主要介绍维护CISSP证书的2个必备条件及16个CPE学分官方获取渠道。 1. 证书维持的2个必备…

AI大模型探索之路-训练篇10:大语言模型Transformer库-Tokenizer组件实践

系列篇章&#x1f4a5; AI大模型探索之路-训练篇1&#xff1a;大语言模型微调基础认知 AI大模型探索之路-训练篇2&#xff1a;大语言模型预训练基础认知 AI大模型探索之路-训练篇3&#xff1a;大语言模型全景解读 AI大模型探索之路-训练篇4&#xff1a;大语言模型训练数据集概…

springcloud微服务搭建多数据源(mysql,oracle,postgres,等等)管理模块,支持通过注解方式切换不同类型的数据库

1.背景 同一套微服务管理系统&#xff0c;业务完全一样&#xff0c;但不同的客户可能要求使用自己熟悉的数据库&#xff0c;比如&#xff0c;mysql&#xff0c;oracle&#xff0c;postgres&#xff0c;还有一些国产数据库。如果能够将数据库模块独立出来&#xff0c;兼容各家的…

Mybatis进阶(映射关系一对一 )

文章目录 1.基本介绍1.基本说明2.映射方式 2.配置xml方式&#xff08;多表联查&#xff09;1.数据库表设计2.新建子模块1.创建子模块2.创建基本结构 3.MyBatisUtils.java和jdbc.properties和mybatis-config.xml与原来的一致4.IdenCard.java5.Person.java6.IdenCardMapper.java7…