基础IO

本文详细介绍了C语言中的文件I/O接口,包括fopen、fclose、fgets等函数的使用,以及Linux系统调用如open、close、read、write和lseek的解释。同时,文章还探讨了文件描述符的概念,重定向原理,以及软硬链接的区别。

标准C的文件io接口:

fopen(file, "w r a b r+ w+ ")          C库中fopen返回的是文件流指针:  FILE*

fclose     fgets     fprintf  

fseek跳转读写位置     printf     sprintf     fprintf

fread    ftell

fwritex

linux下的系统调用io接口:

open

int open(const char *pathhname, int flags, mode_t mode);

pathname:要打开的文件名

flags:选项标志

        O_RDONLY:只读

        O_WRONLY:只写

        O_RDWR:读写

        O_CREAT文件不存在则创建,存在则打开

        O_EXCL:与O_CREAT同用,若文件存在则报错

        O_TRUNC:打开文件的同时,清空文件原有内容

        O_APPEND:追加

mode:文件权限,用于创建文件的时候

返回值:正确:非负值(文件描述符) 错误:-1

close

read

返回实际读取到的数据长度

write

ssize_t write(int fd, const void *buf, size_t,count)

fd:文件描述符

buf:要写入的数据

count:要写入的数据长度

返回值:实际的写入数据长度

lseek

off_t lseek(int fd, off_t offset, int whence);

fd:文件描述符

offset:偏移值

whence:偏移起始位置

SEEK_SET:文件起始位置

SEEK_CUR:当前读写位置

SEEK_END:文件末尾位置

fileno  fdopen  ftruncate

库函数跟系统调用接口的关系:库函数就是系统调用接口的一层封装

文件描述符:

pcb中对文件的描述的一个结构体(file)数组下标

文件描述符是一个数字,那么一个数字是如何描述文件的呢?

一个进程要对所有打开的文件进行管理,先将文件描述起来,然后组织起来进行管理

进程中对文件进行描述的结构体:file(struct file*)

进程使用了一个结构体数组来组织这些描述,而文件描述符就是这个结构体数组的下标。

 

一个程序运行起来之后,默认就打开了三个文件:

标准输入,标准输出, 标准错误

stdin           stdout           stderr             FILE*       文件流指针

  0                 1                    2                  int           文件描述符

我们所说的缓冲区(printf),用户态的一个缓冲区,是文件流指针自带的。

printf,fwrite这些可函数都是先把数据写入到缓冲区中 ,等缓冲区写满了或者一些其他条件满足然后才会真正的写入到文件中,而系统调用没有这个用户态的缓冲区(是直接将数据写入到文件中)。

文件描述符的分配规则:

最小未使用分配原则

重定向原理:

将原本描述符所对应的下标的文件描述修改成了另一个文件的描述,这样的话,描述符没有变,但是真正通过描述符操作的这个文件已经改变了。

linux下的文件系统:ext2

访问一个文件的步骤:

文件系统:

超级块, inode_map, data_map, inode, data

软硬链接:

软硬链接区别:

1.软链接可以针对目录创建,而硬链接不可以

2.软链接是一个新的文件,而硬链接是源文件的一个别名(跟源文件使用相同的inode节点)

3.软链接可以跨分区建立,但是硬链接不可以

4.源文件删除后,软链接就找不着源文件了,但是硬链接没有什么影响,仅仅是链接数-1

动态库和静态库

gcc默认链接方式:动态链接——链接是动态库

静态链接需要加上-static的gcc链接选项——链接的是静态库

静态库(.a):程序在便宜链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。

动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。

程序的编译过程:预处理->编译->汇编->链接

生成一个库其实就是将所有的代码都打包起来,最终得到一个库文件。

生成动态库:gcc   --share   test.c -o libtest.so

编译选项:-fPIC

生成静态库:ar(创建)cr(替换)    libtest.a test.c

动态库和静态库都是给其他代码使用的,意味着库中不能有main函数。

如何链接一个库生成可执行程序

gcc main.c -o main -L/ -ltest(当前路径下)

-L用于指定库的查找路径

-l用于指定链接库的名称

<think>好的,我现在需要帮助用户了解Linux下的基础IO操作教程。根据用户提供的引用内容,我需要整合这些信息,并按照系统级指令的要求来组织回答。首先,用户提到引用了四个不同的来源,其中引用了Linux基础IO、进程控制、文件操作以及标准IO和系统调用IO的区别等内容。 首先,我需要确保回答结构清晰,分步骤解释Linux的基础IO操作。根据引用[2],Linux中一切皆文件,包括标准输入输出和硬件外设,所以应该从文件描述符和文件操作的系统调用开始。然后,引用[3]和[4]提到了标准IO和系统调用IO的区别,需要详细说明两者的不同以及使用场景。用户可能对如何打开、读写文件,以及文件描述符的管理感兴趣。 接下来,按照系统级指令,所有行内数学表达式需要用$...$格式,但在这个问题中可能数学公式较少,更多是代码和命令。独立公式如果需要的话用$$...$$,不过可能这里不需要。需要检查LaTeX语法是否正确,使用中文回答,并生成相关问题。 然后,根据用户提供的引用内容,需要将相关知识组织成教程。例如,文件描述符的概念、系统调用如open、read、write、close的使用,标准库函数如fopen、fread、fwrite,以及两者的区别和选择。此外,可能需要提到文件权限、缓冲机制等。 还要注意引用标识的正确添加,例如在提到一切皆文件时引用[^2],在标准IO和系统调用IO的区别时引用[^3],在提到fwrite参数时引用[^4]。同时,用户的问题是关于基础IO操作的教程,因此需要涵盖基本操作步骤、常用函数和示例代码。 最后,生成相关问题,可能需要包括系统调用与标准库函数的比较、文件描述符的管理、缓冲机制的影响等。 现在需要将这些内容整合成一个结构清晰的中文回答,符合用户指定的格式,包括代码块和引用标注,最后生成相关问题列表。</think>### Linux 基础 IO 操作教程 #### 一、文件描述符与“一切皆文件”原理 在 Linux 中,所有硬件设备(如键盘、显示器)和软件资源(如普通文件)均被视为**文件对象**。操作系统通过统一的接口(读方法、写方法)驱动这些对象,并使用文件描述符(`fd`)进行管理。例如,标准输入(键盘)对应 `fd=0`,标准输出(显示器)对应 `fd=1`,标准错误对应 `fd=2`[^2]。 #### 二、系统调用 IO 操作 1. **打开文件** 使用 `open` 函数: ```c #include <fcntl.h> int fd = open("test.txt", O_RDWR | O_CREAT, 0644); // 权限模式 0644 ``` - 参数:文件名、标志位(如 `O_RDONLY` 只读)、权限 - 返回值:成功返回文件描述符,失败返回 -1 2. **读写文件** - `read` 函数: ```c ssize_t num = read(fd, buffer, sizeof(buffer)); // 返回实际读取字节数 ``` - `write` 函数: ```c ssize_t num = write(fd, "Hello", 5); // 返回实际写入字节数 ``` 3. **关闭文件** ```c close(fd); // 释放文件描述符 ``` #### 三、标准 IO 库函数 标准 IO(如 `fopen`)通过**用户空间缓冲区**提升效率,适合高频小数据操作[^3]。 1. **打开文件** ```c FILE* fp = fopen("test.txt", "r+"); // 模式包括 "r"(读)、"w"(写) ``` 2. **读写操作** - `fread`: ```c size_t count = fread(buffer, sizeof(char), 100, fp); // 读取100个char类型数据 ``` - `fwrite`: ```c fwrite("Data", 1, 4, fp); // 参数:数据指针、块大小、块数量、文件指针 ``` 3. **关闭文件** ```c fclose(fp); // 刷新缓冲区并关闭 ``` #### 四、系统调用 IO 与标准 IO 的选择 | **场景** | **推荐方法** | **原因** | |------------------------|-------------------|-----------------------------| | 高频小数据读写 | 标准 IO(如 `fprintf`) | 缓冲区减少系统调用次数 | | 直接访问硬件驱动程序 | 系统调用 IO | 绕过缓冲区,直接操作底层 | #### 五、关键概念解析 - **文件描述符表**:每个进程独立维护,通过 `fd` 索引内核中的文件对象。 - **缓冲机制**:标准 IO 的三种缓冲模式(全缓冲、行缓冲、无缓冲)通过 `setvbuf` 设置。 ```c // 示例:复制文件内容(系统调用 IO) #include <unistd.h> #include <fcntl.h> int main() { int src_fd = open("src.txt", O_RDONLY); int dest_fd = open("dest.txt", O_WRONLY | O_CREAT, 0644); char buf[1024]; ssize_t num; while ((num = read(src_fd, buf, sizeof(buf))) > 0) { write(dest_fd, buf, num); } close(src_fd); close(dest_fd); return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值