当前位置: 首页 > web >正文

Linux系统之----基础IO

1.基础概念: 

文件与内容操作

文件由内容和属性组成。内容是文件存储的数据,而属性可能包括文件的创建时间、修改时间、权限等。对文件的操作可以分为对内容的操作和对属性的操作。

文件的打开

在访问一个文件之前,通常需要先将其打开。这是因为操作系统需要将文件加载到内存中,以便进行读写操作。如果一个文件没有被打开,它就存在于磁盘上,而不是在内存中

谁打开文件

用户可以通过命令行(如bash)启动进程来打开文件。进程是操作系统进行资源分配和调度的基本单位。

操作系统的角色

操作系统负责管理文件的打开和关闭。它确保进程能够安全地访问文件,并且在不需要时释放资源。操作系统通过系统调用(如open)来打开文件,这是进程与操作系统交互的一种方式。

文件描述符

操作系统使用文件描述符来跟踪每个打开的文件。文件描述符是一个数字,用于在程序中引用特定的文件。一定存在一种数据结构体(如进程控制块PCB)来描述被打开的文件,这有助于操作系统管理文件的打开状态。

进程与文件的关系

进程有task_struct,这是操作系统用来描述进程的数据结构。它包含了进程的状态信息,包括打开的文件。研究进程与文件的关系,实际上是研究进程如何通过操作系统来访问和管理文件。

 2.fopen函数:

2.1 函数原型

 2.2 参数解释


pathname就是路径名,就是你想打开的那个文件的路径

mode是指文件的打开模式,具体的模式可以参考下图

只读模式 ("r"):打开一个已经存在的文件,用于读取操作。如果文件不存在,返回 NULL

写入模式 ("w"):打开一个文件,用于写入操作。如果文件不存在,创建新文件。如果文件已存在,清空文件内容。

追加模式 ("a"):打开一个文件,用于追加写入操作。如果文件不存在,创建新文件。如果文件已存在,写入内容追加到文件末尾。

读写模式 ("r+"):打开一个已经存在的文件,用于读写操作。文件指针放在文件的开头。

写入和读取模式 ("w+"):打开一个文件,用于读写操作。如果文件不存在,创建新文件。如果文件已存在,清空文件内容。文件指针放在文件的开头。

追加和读取模式 ("a+"):打开一个文件,用于追加写入和读取操作。如果文件不存在,创建新文件。如果文件已存在,写入内容追加到文件末尾。文件指针放在文件的末尾。

二进制只读模式 ("rb"):类似于只读模式,但用于二进制文件。

二进制写入模式 ("wb"):类似于写入模式,但用于二进制文件。

二进制追加模式 ("ab"):类似于追加模式,但用于二进制文件。

二进制读写模式 ("rb+"):类似于读写模式,但用于二进制文件。

二进制写入和读取模式 ("wb+"):类似于写入和读取模式,但用于二进制文件。

二进制追加和读取模式 ("ab+"):类似于追加和读取模式,但用于二进制文件。

2.3 返回值

成功时,fopen 返回一个指向 FILE 结构的指针,该结构用于后续的文件操作。如果打开文件失败,返回 NULL,并设置 errno 以指示错误原因。

2.4 错误处理

如果文件打开失败,可以通过检查返回值是否为 NULL 来确定。可以使用 perrorstrerror 函数来获取错误描述。

2.5 代码示例

#include <stdio.h>int main() {FILE *fp;fp = fopen("example.txt", "r"); // 以只读模式打开文件if (fp == NULL) {perror("Error opening file");return -1;}// 进行文件操作...fclose(fp); // 关闭文件return 0;
}

2.6 注意事项

1、文件指针fopen 返回的 FILE 指针用于后续的文件读写操作。

2、文件路径fopen 需要文件的完整路径或相对于当前工作目录的路径。当前工作目录(CWD)可以通过 getcwd 函数获取。

3、文件模式:不同的模式允许不同的文件操作,如读取、写入、追加等。

4、使用 fopen 打开文件后,应该在完成文件操作后调用 fclose 来关闭文件,以释放资源。

5、在处理文件时,始终检查 fopen 的返回值,以确保文件正确打开。

 3.echo

当我们输入echo "hello word" > log.txt的时候,会重定向到log.txt文件中,必须先打开这个文件,之后才能写入,默认是w方式,所以我们下次写的时候如果用>,原文件内容就会被清空,而如果使用>>就不会

4.输出信息到显示器的方法

1.通过键盘输入数字(如12345),讨论输入的是int 12345还是一个1 2 3 4 5,答案是后者,说明显示器被叫做字符设备

2.我今天向显示器写入12345,我是写了一个int 12345 ,还是向显示器写入了int 12345?答案是向显示器写入了字符1 2 3 4 5 ,所以说显示器是字符设备!!

5.标准输入输出流

标准输入输出流:

stdin:标准输入流,通常与键盘文件关联。

stdout:标准输出流,通常与显示器文件关联。

stderr:标准错误流,通常与显示器文件关联,用于输出错误信息。

而我们的进程在启动的时候,会默认打开三个输入输出流,本质上就是打开三个文件,换句话说,凡是使用CPU计算的,都要进程默认打开对应的文件

那我们不妨来查看一下这三个标准流:

我们输入man 3 stdin

6.fopen

 首先我们查看一下这个函数

6.1 参数解释

  1. pathname:

    • 文件路径和文件名。用于指定要打开或创建的文件。

     2.flags:

               打开文件的方式,由一组标志位组合而成。常用的标志包括:

    O_RDONLY:以只读方式打开。

    O_WRONLY:以只写方式打开。

    O_RDWR:以读写方式打开

    O_APPEND:写入时追加到文件末尾。

    O_CREAT:如果文件不存在,则创建它,并使用mode参数指定的权限。

    O_TRUNC:如果文件存在,则截断文件长度为0。

这些标志可以使用按位或运算符(|)组合,例如:

open("file.txt", O_RDWR | O_CREAT, 0644);

 实际上,这些每个标志都是一个宏,定义为一个数字,其中只有一个比特位是1,其他位是0。这样可以通过按位或运算符组合多个标志。

3.mode:

文件权限模式,用于指定新创建文件的权限。权限模式是一个mode_t类型的值,通常由以下三位权限组成:即前文所讲的rwx,也可以用数字表示,如666是所有权限均为可读可写,rw-

注意:

1.如果文件已经存在,可以只使用两个参数(pathnameflags)来打开文件

6.2 位图传递标志位

6.2.1 定义

位图传递标志位是一种通过位运算组合多个标志位的方法。在文件操作中,标志位用于指定文件的打开模式(如只读、只写、读写、追加等)。每个标志位是一个单独的位,通过按位或运算符(|)将它们组合在一起。

6.2.2 常见的标志位总结

标志位描述
O_RDONLY以只读方式打开文件
O_WRONLY以只写方式打开文件
O_RDWR以读写方式打开文件
O_APPEND写入时追加到文件末尾
O_CREAT如果文件不存在,则创建文件
O_TRUNC如果文件存在,则截断文件长度为0
O_EXCLO_CREAT一起使用,如果文件已存在则打开失败

6.2.3 位图传递标志位的原理

每个标志位对应一个独立的位,通常定义为宏,表示为一个数字,其中只有一个比特位为1。例如

#define O_RDONLY  00
#define O_WRONLY  01
#define O_RDWR    02
#define O_APPEND  04
#define O_CREAT   0100
#define O_TRUNC   01000
#define O_EXCL    02000

这些宏定义允许通过按位或运算符组合多个标志位。例如:

int flags = O_RDWR | O_APPEND | O_CREAT;

上述代码组合了读写模式、追加模式和创建模式。

 6.2.4 优点

灵活性:允许组合多个标志位,满足不同的文件操作需求。

可读性:通过宏定义,使代码更具可读性,易于理解和维护。

跨平台性:位图传递标志位在不同操作系统上可能具有不同的定义,但其使用方式类似。跨平台编程中,标准库函数(如fopen)会封装这些差异,提供统一的接口。

7.文件描述符

7.1 定义

在操作系统中,文件描述符(File Descriptor,FD)是一个用于访问文件的整数,它是一个数组索引,指向内核中的文件描述符表。文件描述符表维护了文件的状态和操作信息。

7.2 文件描述符的管理

内核管理:每个进程都维护着一个文件描述符表,包含多个文件描述符。内核通过这些描述符来管理文件的打开、读取、写入和关闭操作。

标准文件描述符:通常,进程启动时会默认打开三个文件描述符:

0:标准输入(stdin

1:标准输出(stdout

2:标准错误(stderr

7.3 跨平台性

跨平台性是指软件能够在多种不同的操作系统上运行,无需修改或只需少量修改。在文件操作中,不同操作系统(如Linux、Windows、macOS)可能有不同的文件接口和实现方式。

7.3.1为什么需要跨平台性?

1.提高语言竞争力:支持跨平台可以让编程语言吸引更广泛的用户群体,提升其使用率和影响力。

2.便捷性:开发者无需针对不同平台编写不同代码,降低了开发成本和复杂度。

7.3.2 如何实现跨平台性?

标准库封装:高级语言通常会提供标准库封装底层的系统调用,如C语言的<stdio.h>库。这些库在不同平台上实现细节可能不同,但对开发者提供了统一的接口。

Linux:调用openread等系统调用。

Windows:调用CreateFileReadFile等API。

条件编译:开发者使用条件编译指令(如#ifdef)来编写可在不同平台运行的代码。

#ifdef LINUX// Linux系统调用
#elif defined(WIN32)// Windows API调用
#endif

http://www.xdnf.cn/news/6276.html

相关文章:

  • 亚马逊电商广告革命:当AI推荐沦为红海陷阱,中国卖家如何破局?
  • AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年5月14日第77弹
  • 最短路与拓扑(2)
  • vim启动的时候,执行gg
  • 现场维护三重四极杆质谱系统和四极杆清洗方法,确保所有目标化合物的可靠性检测
  • 牛顿均差知识
  • 写作--简单句基础练习
  • AI时代的弯道超车之第九章:AI如何改变传统教育模式
  • C PRIMER PLUS——第10节:结构体、共用(同)体/联合体
  • 字符串检索算法:KMP和Trie树
  • React学习———useEffect和useLayoutEffect
  • 数据防泄密安全:企业稳健发展的守护盾
  • 安卓开饭-ScrollView内嵌套了多个RecyclerView,只想与其中一个RecyclerView有联动
  • Kite AI 自动机器人部署教程
  • 使用深度学习预训练模型检测物体
  • MQTT 在Spring Boot 中的使用
  • 第二章 变量和运算符
  • C++取时间戳窗口
  • 在线黑白图像转换:简单却强大的视觉表达工具
  • 计算机组成原理:I/O
  • 死信队列-常见的业务场景
  • gd32e230c8t6 keil6工程模板
  • 关于嵌入式系统的知识课堂(一)
  • 2天长沙旅游规划
  • 几种运放典型应用电路
  • Vue:显示数据
  • HTML 颜色全解析:从命名规则到 RGBA/HSL 值,附透明度设置与场景应用指南
  • Flutter - UIKit开发相关指南 - 线程和异步
  • Seed1.5-VL:高效通用的视觉-语言基础模型
  • leetcode - 滑动窗口问题集