从零开始的敲代码生活--Linux应用软件(文件操作基础2)
2026/9/3 6:21:17 网站建设 项目流程

一、文件IO

文件IO是Linux内核提供的文件操作接口,属于系统调用。 核心接口:open()read()write()close()

1. open 打开文件

#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode);

功能:打开一个文件,获取文件描述符。

参数说明

  • pathname:待打开文件路径名称
  • flags:打开方式标志位,可以多标志位按位或组合
flags含义
O_RDONLY只读
O_WRONLY只写
O_RDWR读写
O_CREAT文件不存在则创建
O_TRUNC打开时清空文件内容
O_APPEND追加模式,写在文件末尾

标准IO mode 和 文件IO flags对应关系

标准IO mode文件IO flags
"r"O_RDONLY
"r+"O_RDWR
"w"O_WRONLY | O_TRUNC | O_CREAT,0664
"w+"O_RDWR | O_TRUNC | O_CREAT,0664
"a"O_WRONLY | O_CREAT | O_APPEND,0664
"a+"O_RDWR | O_CREAT | O_APPEND,0664
  • mode:新建文件权限,实际权限 =mode & ~umask;普通文件常用0664,满权限0777

返回值:成功返回文件描述符,失败返回-1

文件描述符 打开文件后内核分配的非负小整数;范围默认0‑1023,共1024个;分配规则:取当前最小未被使用的编号。 系统默认已经打开:

标准IO文件IO文件描述符宏
stdin0(STDIN_FILENO)
stdout1(STDOUT_FILENO)
stderr2(STDERR_FILENO)

2. close 关闭文件

#include <unistd.h> int close(int fd);

参数:fd为文件描述符。 返回:成功0,失败‑1

注意:打开后必须关闭,否则发生文件描述符泄漏。

3. write 写数据

ssize_t write(int fd, const void *buf, size_t count);
  • fd:文件描述符
  • buf:待写入数据缓冲区首地址
  • count:期望写入字节数 返回:成功返回实际写入字节数;失败返回‑1

4. read 读数据

ssize_t read(int fd, void *buf, size_t count);
  • fd:文件描述符
  • buf:存放读取数据的缓冲区
  • count:期望读取字节数 返回:成功返回实际读到字节数;读到文件末尾返回0;失败返回‑1

5. read + write 实现文件拷贝

int file_copy(const char *srcfile, const char *dstfile) { int fdsrc = open(srcfile, O_RDONLY); int fddst = open(dstfile, O_WRONLY | O_CREAT | O_TRUNC, 0664); if (-1 == fdsrc || -1 == fddst) { printf("open error\n"); return -1; } char buff[1024] = {0}; ssize_t size = 0; while ((size = read(fdsrc, buff, sizeof(buff))) > 0) { write(fddst, buff, size); } close(fdsrc); close(fddst); return 0; }

6. lseek 文件定位

off_t lseek(int fd, off_t offset, int whence);
  • offset:偏移字节数
  • whence偏移基准:
    • SEEK_SET:文件开头
    • SEEK_CUR:当前读写位置
    • SEEK_END:文件末尾 返回:成功返回当前距离文件开头偏移量;失败返回‑1

二、文件IO和标准IO的区别

对比项标准IO文件IO
操作对象FILE *(文件流指针)fd(文件描述符int)
函数来源C库函数,可移植性强Linux系统调用,可移植弱
缓冲区用户层带缓冲区,减少系统调用,效率高无用户层缓冲区,实时性好
适用场景普通文件读写普通文件、硬件设备文件

缓冲区分类

  1. 行缓冲:终端交互,默认1024字节;\n、程序结束、fflush、缓冲区满触发刷新。
  2. 全缓冲:普通文件,默认4096字节;关闭文件、程序结束、缓冲区满、fflush触发刷新。
  3. 无缓冲:stderr标准错误输出,直接输出。

三、目录IO

目录操作API:opendirreaddirclosedirmkdir

1. opendir 打开目录

DIR *opendir(const char *name);

参数:目录名;返回目录流指针;失败返回NULL

2. closedir 关闭目录

int closedir(DIR *dirp);

返回成功0,失败‑1

3. readdir 读取目录项

struct dirent *readdir(DIR *dirp);

返回struct dirent*,读到目录末尾/出错返回NULL

struct dirent { ino_t d_ino; /* inode编号 */ off_t d_off; unsigned short d_reclen; unsigned char d_type;/* 文件类型 */ char d_name[256]; /* 文件名 */ };

4. mkdir 创建目录

int mkdir(const char *pathname, mode_t mode);

参数:目录名,目录权限;成功返回0,失败‑1

创建文件对比:

  • mkdir:创建文件夹
  • touch命令:创建普通文件
  • open()/fopen():代码内创建普通文件

目录遍历示例代码

遍历/dev目录,过滤隐藏文件,打印文件名与inode号

int main(void) { DIR *pdir = opendir("/dev"); if (NULL == pdir) { printf("opendir error\n"); return -1; } while (1) { struct dirent *pinfo = readdir(pdir); if (NULL == pinfo) { break; } if ('.' == pinfo->d_name[0]) { continue; } printf(" %s : %ld\n", pinfo->d_name, pinfo->d_ino); } closedir(pdir); return 0; }

四、其他常用接口

1. 格式化输出系列

int printf(const char *format, ...); int fprintf(FILE *stream, const char *format, ...); int dprintf(int fd, const char *format, ...); int sprintf(char *str, const char *format, ...);
  • printf:输出到标准输出stdout
  • fprintf:格式化输出到文件流FILE*
  • dprintf:格式化输出到文件描述符fd
  • sprintf:格式化输出到内存字符数组,常用于数字转字符串、字符串拼接

2. strtok 字符串分割

char *strtok(char *str, const char *delim);

功能:按分隔符delim切割字符串;第一次传入原字符串,后续调用传NULL;返回分割得到子串首地址;分割完毕返回NULL

⚠会修改原字符串。

3. 出错处理函数

char *strerror(int errnum); void perror(const char *s);
  • strerror:将错误码errno转为错误信息字符串。
  • perror:打印自定义提示字符串 + 系统错误原因。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询