Posts 再读APUE——文件IO
Post
Cancel

再读APUE——文件IO

1. POSIX 接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 1. 如何看函数接口是否符合 POSIX 接口?
       1   Executable programs or shell commands
       2   System calls (functions provided by the kernel)  // 符合 POSIX
       3   Library calls (functions within program libraries) // 符合 POSIX
       4   Special files (usually found in /dev)
       5   File formats and conventions eg /etc/passwd
       6   Games
       7   Miscellaneous (including macro packages and conventions), e.g. man(7), groff(7)  // 杂项内容 EPOLL TCP UDP 等参数
       8   System administration commands (usually only for root) // 不符合 epoll 等
       9   Kernel routines [Non standard]

// 也可以通过 man xx 来看
// man 2 open

CONFORMING TO
       open(), creat() SVr4, 4.3BSD, POSIX.1-2001, POSIX.1-2008.
1
2
// 2. 顺便插播一条 man 如何查看tpc 等参数
xm@hcss-ecs-4208:~$ man 7 tcp   (tcp_max_tw_buckets等)

2. 进程的标准输入输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 1. 概览
当 Linux/Unix ​​启动一个新进程​​(如运行你的程序)时,会自动创建 3 个默认的文件描述符(File Descriptor):

​​名称​​	​​文件描述符 (fd)​​	​​默认目标​​	​​用途​​
​​标准输入 (stdin)​​	0	键盘	读取输入数据
​​标准输出 (stdout)​​	1	屏幕	输出正常结果
​​标准错误 (stderr)​​	2	屏幕	输出错误消息(与 stdout 独立)

// 2. 重定向基础语法

​操作​​	​                     ​命令示例​​	           ​​说明​​
​​重定向 stdout 到文件​​	command > output.log	覆盖写入文件(若文件不存在则创建)
​​追加 stdout 到文件​​	command >> output.log	追加到文件末尾
​​重定向 stderr 到文件​​	command 2> error.log	仅将错误信息写入文件(2> 中的 2 是 stderr 的文件描述符)
​​丢弃 stderr(输出到黑洞)​​	command 2> /dev/null	将错误信息丢弃(/dev/null 是特殊设备文件,会吞没所有写入的数据)
合并重定向到同一文件      command > combined.log 2>&1     先重定向 stdout 到文件,再将 stderr 重定向到 stdout 的当前位置(即文件)。

3. 进程的有效id

1
2
3
4
身份类型​​	​​存储位置​​	​​作用​​
​​真实用户 ID (RUID)​​	/proc/[pid]/status  Uid 字段	进程的实际所有者(通常是启动进程的用户)。
​​有效用户 ID (EUID)​​	/proc/[pid]/status  Uid 字段	内核用于权限检查的 ID(决定进程能做什么)。
​​保存的用户 ID (SUID)​​	/proc/[pid]/status  Uid 字段	用于临时切换回原始权限(如特权操作后恢复低权限)。

4. 标准 IO 流

在 Linux 中,​​I/O 流​​ 和 ​​文件描述符(fd)​​ 是处理输入/输出的两种不同抽象层次的概念,它们既有联系又有显著区别。 其实就是一个系统库函数 & 一个标准库函数, 一个有缓存一个直接内核操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 1. 什么是io 流
​​I/O 流​​  ​​高级别的抽象​​,由标准库(如 C  stdio.h  C++  iostream)提供,封装了底层系统调用(如 read/write),提供缓冲、格式化等便捷功能。
缓冲机制​​:默认启用缓冲区(减少系统调用次数),支持**行缓冲****全缓冲****无缓冲**三种模式。

#include <stdio.h>
FILE *fp = fopen("file.txt", "r");  // 打开文件流
char buf[100];
fgets(buf, sizeof(buf), fp);        // 带缓冲的读取
fclose(fp);

// 2. 文件描述符(File Descriptor, fd)​​
​​文件描述符​​  ​​低级别的抽象​​,由操作系统内核直接提供,是一个非负整数(如 0=stdin, 1=stdout, 2=stderr),代表内核中打开的文件、管道、套接字等资源的引用。
​​无缓冲​​:直接调用系统调用(如 read/write),每次操作可能触发内核交互。

#include <unistd.h>
#include <fcntl.h>
int fd = open("file.txt", O_RDONLY);  // 获取文件描述符
char buf[100];
read(fd, buf, sizeof(buf));           // 无缓冲的读取
close(fd);

// 3. 流 IO 的三种方式
1. 读取单个字符(Character)​
2. 逐行读取(Line
3. ​全 I/OBulk/Buffered)​
// 全IO
FILE *fp = fopen("data.bin", "rb");
char buffer[4096];
size_t n;
while ((n = fread(buffer, 1, sizeof(buffer), fp)) > 0) {
    write(STDOUT_FILENO, buffer, n);  // 处理数据块
}
fclose(fp);
This post is licensed under CC BY 4.0 by the author.

Contents

Trending Tags