从零开始的敲代码生活--Linux应用软件(文件操作基础2)

发布时间:2026/9/3 6:21:18
从零开始的敲代码生活--Linux应用软件(文件操作基础2) 一、文件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 flagsrO_RDONLYrO_RDWRwO_WRONLY | O_TRUNC | O_CREAT,0664wO_RDWR | O_TRUNC | O_CREAT,0664aO_WRONLY | O_CREAT | O_APPEND,0664aO_RDWR | O_CREAT | O_APPEND,0664mode新建文件权限实际权限 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系统调用可移植弱缓冲区用户层带缓冲区减少系统调用效率高无用户层缓冲区实时性好适用场景普通文件读写普通文件、硬件设备文件缓冲区分类行缓冲终端交互默认1024字节\n、程序结束、fflush、缓冲区满触发刷新。全缓冲普通文件默认4096字节关闭文件、程序结束、缓冲区满、fflush触发刷新。无缓冲stderr标准错误输出直接输出。三、目录IO目录操作APIopendir、readdir、closedir、mkdir。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输出到标准输出stdoutfprintf格式化输出到文件流FILE*dprintf格式化输出到文件描述符fdsprintf格式化输出到内存字符数组常用于数字转字符串、字符串拼接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打印自定义提示字符串 系统错误原因。