Linux 系统编程笔记整理
一、文件类型(7种)
使用 ll 或 ls -l 查看文件类型:
drwxrwxr-x # d 目录文件
lrwxrwxrwx # l 符号链接(软链接)
-rw-rw-r-- # - 普通文件
crw------- # c 字符设备文件
brw-rw---- # b 块设备文件
srwxrwxrwx # s 套接字文件
prw------- # p 管道文件
详细说明:
-
d 目录文件 - 用
cd进入 -
l 符号链接 - 类似 Windows 快捷方式
-
- 普通文件 - 文本、图片、可执行文件等
-
c 字符设备 - 按字符访问的设备(键盘、鼠标等)
-
b 块设备 - 按块访问的存储设备(硬盘、U盘等)
-
s 套接字 - 网络通信相关
-
p 管道文件 - 进程间通信
二、命令行参数
// 执行: ./a.out arg1 arg2 arg3
int main(int argc, char *argv[])
{
printf("参数个数: %d\n", argc); // 包含程序名本身
for(int i = 0; i < argc; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
return 0;
}
三、man 手册
man man # 查看所有man帮助
man 1 ls # 查看ls命令
man 2 open # 查看open系统调用
man 3 fopen # 查看fopen库函数
四、标准IO(带缓冲区)
1. 文件打开模式
| 模式 | 说明 | 注意事项 |
|---|---|---|
| r | 只读,文件必须存在 | |
| r+ | 读写,文件必须存在 | |
| w | 只写,创建/清空文件 | |
| w+ | 读写,创建/清空文件 | |
| a | 追加写,创建文件 | 写位置在文件末尾 |
| a+ | 追加读写,创建文件 | 写末尾,读开头 |
2. 标准IO函数
FILE *fopen(const char *pathname, const char *mode);
// 字符操作
int fputc(int c, FILE *stream); // 写一个字符
int fgetc(FILE *stream); // 读一个字符
// 字符串操作
int fputs(const char *s, FILE *stream); // 写字符串
char *fgets(char *s, int size, FILE *stream); // 读字符串
// 块操作
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
int fclose(FILE *stream); // 关闭文件
3. 标准流指针
stdin // 标准输入(键盘)
stdout // 标准输出(屏幕)
stderr // 标准错误(屏幕)
4. 文件定位
int fseek(FILE *stream, long offset, int whence);
// whence: SEEK_SET(开头), SEEK_CUR(当前位置), SEEK_END(末尾)
long ftell(FILE *stream); // 获取当前位置
void rewind(FILE *stream); // 回到文件开头
五、缓冲类型
| 类型 | 大小 | 适用场景 | 刷新条件 |
|---|---|---|---|
| 行缓冲 | 1KB | 终端(stdout) | 1.遇到\n 2.缓冲区满 3.程序结束 4.fflush() |
| 全缓冲 | 4KB | 文件操作 | 1.缓冲区满 2.程序结束 3.fflush() |
| 无缓冲 | 0 | stderr | 立即输出 |
六、文件IO(系统调用,无缓冲区)
1. 文件描述符
int fd; // 文件描述符(0,1,2已被占用)
// 0: stdin, 1: stdout, 2: stderr
2. 基本操作
#include <fcntl.h>
#include <unistd.h>
// 打开文件
int open(const char *pathname, int flags, mode_t mode);
// flags: O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC, O_APPEND
// 读写文件
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
// 关闭文件
int close(int fd);
3. 示例
int fd = open("test.txt", O_RDWR | O_CREAT, 0644);
if (fd < 0) {
perror("open failed");
return -1;
}
char buf[100];
ssize_t n = read(fd, buf, sizeof(buf));
write(fd, "hello", 5);
close(fd);
七、目录操作
#include <dirent.h>
DIR *opendir(const char *name); // 打开目录
struct dirent *readdir(DIR *dirp); // 读取目录项
int closedir(DIR *dirp); // 关闭目录
// dirent结构体
struct dirent {
ino_t d_ino; // inode号
off_t d_off; // 偏移量
unsigned short d_reclen; // 记录长度
unsigned char d_type; // 文件类型
char d_name[256]; // 文件名
};
目录遍历示例
DIR *dir = opendir(".");
if (dir == NULL) {
perror("opendir");
return -1;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
closedir(dir);
八、标准IO vs 文件IO
| 特性 | 标准IO | 文件IO |
|---|---|---|
| 接口 | 库函数 | 系统调用 |
| 缓冲 | 有 | 无 |
| 操作对象 | FILE*流指针 | int文件描述符 |
| 适用场景 | 普通文件 | 设备文件 |
| 性能 | 较高(批量操作) | 较低(实时) |
| 移植性 | 好(跨平台) | 差(Linux特定) |
九、Makefile
基础版本
makefile
a.out: main.c func.c
gcc main.c func.c -o a.out
clean:
rm a.out
使用变量
makefile
SRC = main.c
SRC += func.c
APP = a.out
FLAG = -g
$(APP): $(SRC)
gcc $^ -o $@ $(FLAG)
clean:
rm $(APP)
自动变量
-
$@- 目标文件名 -
$^- 所有依赖文件 -
$<- 第一个依赖文件
常用命令
make # 编译
make clean # 清理
make -f mymake # 指定makefile文件
十、常用头文件
#include <stdio.h> // 标准IO
#include <fcntl.h> // 文件控制
#include <unistd.h> // 系统调用
#include <dirent.h> // 目录操作
#include <sys/types.h> // 系统类型
#include <sys/stat.h> // 文件状态
#include <stdlib.h> // 标准库
#include <string.h> // 字符串操作
十一、文件操作步骤总结
标准IO步骤:
-
打开文件 -
fopen() -
读写操作 -
fread()/fwrite(),fgets()/fputs(),fgetc()/fputc() -
定位操作 -
fseek(),ftell(),rewind() -
关闭文件 -
fclose()
文件IO步骤:
-
打开文件 -
open() -
读写操作 -
read()/write() -
定位操作 -
lseek() -
关闭文件 -
close()
目录操作步骤:
-
打开目录 -
opendir() -
读取目录项 -
readdir() -
关闭目录 -
closedir()