目录文件描述符文件操作的步骤一打开 -- open系统调用1. 函数原型2. 参数详解3. 返回值4. 主要 flags参数详解二读文件 -- read1.函数原型2. 参数详解3. 返回值详解三写入文件 -- write1. 函数原型2. 参数详解3. 返回值详解四文件定位 -- lseek函数1. 函数原型2. 功能3. 参数详解4. whence参数5. 返回值详解6. 关键特性和用法核心使用要点与注意事项系统调用操作系统为了方便用户使用系统功能而对外提供的一组系统函数。关于文件操作的相关函数叫文件io。C库函数c标准库函数c语言程序能够运行的地址默认c库函数都可以调用。 关于文件操作的相关函数叫标准io。标准io和文件io关系文件描述符定义文件描述符是一个非负整数是 Linux 内核用来标识进程打开文件的索引。可以把它理解为文件在特定进程内的“代号”或“编号”。核心特点进程私有每个进程都有自己独立的文件描述符表用于管理本进程打开的所有文件。分配规则文件描述符从0开始顺序分配。标准描述符0、1、2是系统为每个进程预留的三个标准描述符通常关联到终端0 -STDIN_FILENO标准输入默认为键盘。1 -STDOUT_FILENO标准输出默认为屏幕。2 -STDERR_FILENO标准错误输出默认为屏幕。新文件描述符新打开的文件其描述符从3开始分配。文件操作的步骤一打开 --open系统调用1. 函数原型int open(const char *pathname, int flags, mode_t mode);2. 参数详解参数含义说明pathname文件路径需要打开或创建的文件路径字符串。flags打开标志控制文件的打开/创建方式。多个标志用按位或 (\|) 组合。mode权限模式指定新创建文件的访问权限八进制数如0644仅在flags包含O_CREAT时有效。3. 返回值情况返回值成功返回一个非负整数即新打开文件的文件描述符。失败返回-1并设置全局变量errno以指示具体错误。4. 主要flags参数详解flags参数用于指定文件的打开方式是控制open行为的关键。man fopen可以查到这张表标志名称功能与影响O_RDONLY只读打开文件只能用于读取不能写入。O_WRONLY只写打开文件只能用于写入不能读取。O_RDWR读写打开文件既可以读取也可以写入。O_CREAT创建文件如果pathname指定的文件不存在则创建它。需要配合mode参数。O_TRUNC截断文件如果文件已存在且以可写方式 (O_WRONLY或O_RDWR) 打开则将其长度截断为0清空内容。O_APPEND追加模式每次执行write操作时文件偏移量会自动移动到文件末尾保证写入的内容总是被追加到文件尾部。组合使用示例open(“file.txt”, O_RDONLY);// 以只读方式打开已存在的文件open(“log.txt”, O_WRONLY \| O_CREAT \| O_APPEND, 0644);// 以只写、追加模式打开文件不存在则创建权限为rw-r--r--open(“temp.dat”, O_RDWR \| O_CREAT \| O_TRUNC, 0666);// 以读写方式打开文件不存在则创建存在则清空权限为rw-rw-rw-二读文件 -- read1.函数原型ssize_t read(int fd, void *buf, size_t count);2. 参数详解参数数据类型含义与说明fdint文件描述符标识要读取的已打开文件。bufvoid *缓冲区指针指向一片用户空间的内存区域用于存放从文件中读取到的数据。countsize_t请求读取的字节数表示本次希望从文件中最多读取多少个字节到buf中。3. 返回值详解返回值含义与说明 0成功返回实际读取到的字节数。此值可能小于count参数原因包括文件剩余字节不足、从管道或终端读取、被信号中断等。 0表示已到达文件末尾没有更多数据可读。-1失败表示发生了错误。此时会设置全局变量errno以指示具体错误原因如EINTR被信号中断EBADF文件描述符无效等。三写入文件 -- write1. 函数原型ssize_t write(int fd, const void *buf, size_t count);2. 参数详解参数数据类型含义与说明fdint文件描述符标识要写入的已打开文件。bufconst void *数据缓冲区指针指向一片用户空间的内存区域其中包含要写入文件的数据。countsize_t请求写入的字节数表示希望从buf中取出多少个字节写入文件。3. 返回值详解返回值含义与说明 0成功返回实际写入的字节数。在大多数情况下此值等于count。但如果磁盘空间不足、写入被信号中断、或遇到资源限制如 RLIMIT_FSIZE此值可能小于count。 0通常表示没有写入任何数据。对于普通文件这很少见但对于某些特殊文件如管道、套接字可能存在。-1失败表示发生了错误。此时会设置全局变量errno以指示具体错误原因如EINTR被信号中断ENOSPC设备无剩余空间EBADF文件描述符无效等。实现cp功能#include stdio.h #include unistd.h #include fcntl.h int main(int argc, const char *argv[]) { if(argc ! 3) { printf(%s filename filename\n,argv[0]); return -1; } int fd open(argv[1],O_RDONLY|O_CREAT,0666); int fd2 open(argv[2],O_WRONLY|O_CREAT,0666); if(fd 0 || fd2 0) { perror(open fail); return -1; } char buf[1024]; int ret 0; while((ret read(fd,buf,sizeof(buf)))!0) { //buf[ret] \0; // 添加字符串结束符 //printf(ret %d buf %s\n, ret, buf); write(fd2,buf,ret); } return 0; }四文件定位 --lseek函数1. 函数原型#include unistd.h #include sys/types.h off_t lseek(int fd, off_t offset, int whence);2. 功能用于移动文件的读写位置指针实现随机访问。可以读取或写入文件的任意位置而不仅限于顺序从头到尾。3. 参数详解参数数据类型含义与说明fdint文件描述符标识已打开、可定位的文件。offsetoff_t偏移量表示相对于whence指定起点的移动字节数。-正值向文件末尾方向移动向后。-负值向文件开头方向移动向前。whenceint起始位置参考点。决定offset的计算基准是一个整型常量。4.whence参数whence参数通常由以下三个宏定义指定它们是整数常量决定了偏移的起点。宏常量值常见含义与计算基准SEEK_SET0文件开头。从文件开始位置计算偏移。新的偏移量 offset。SEEK_CUR1当前位置。从当前读写指针位置计算偏移。新的偏移量 当前偏移 offset。SEEK_END2文件末尾。从文件结束位置计算偏移。新的偏移量 文件大小 offset。5. 返回值详解返回值含义与说明 0成功返回移动后新的文件偏移量从文件开头算起的字节数。(off_t)-1失败返回-1并设置errno以指示错误如EBADF描述符无效ESPIPE文件不支持定位。重要提示返回值是新的偏移量这是一个非负的、从文件开头计算的字节偏移。即使使用SEEK_CUR或SEEK_END并传入负的offset移动到文件开头之前也会返回-1表示错误而不会成功返回一个负的偏移量。6. 关键特性和用法特性/用法说明与示例获取当前偏移off_t curr_pos lseek(fd, 0, SEEK_CUR);偏移量为0从当前位置计算即返回当前偏移量移动到文件开头lseek(fd, 0, SEEK_SET);移动到文件末尾off_t end_pos lseek(fd, 0, SEEK_END);常用于获取文件大小或为追加写做准备向前/向后移动lseek(fd, 100, SEEK_CUR);// 从当前位置向后移动100字节lseek(fd, -50, SEEK_CUR);// 从当前位置向前移动50字节创建文件空洞如果移动的位置超过了当前文件大小然后执行write操作会在原文件末尾和新写入位置之间形成“空洞”。这部分不占用实际磁盘块读起来是0但会使文件大小增加。核心使用要点与注意事项要点read函数write函数数据流向从文件 (fd) →内存 (buf)从内存 (buf) →文件 (fd)缓冲区管理调用前必须确保buf指向的内存空间足够大至少可容纳count字节。调用前必须确保buf指向的内存区域已包含有效数据。阻塞行为在默认阻塞模式下如果文件中无足够数据如从管道、终端或网络套接字读调用会阻塞直到有数据可读或到达文件尾。在默认阻塞模式下如果由于设备繁忙等原因无法立即写入如向管道写但缓冲区满调用会阻塞直到可以写入。典型用法通常与循环结合使用以处理“实际读取字节数小于请求字节数”的情况确保读取完整数据。通常也应检查返回值在写入大型数据块时可能需要多次调用write以确保所有数据被写入。与标准描述符fd可以为0(STDIN_FILENO)从标准输入读取。fd可以为1(STDOUT_FILENO) 或2(STDERR_FILENO)分别向标准输出或标准错误输出写入。
Linux 系统编程 - 文件IO
发布时间:2026/5/25 10:05:39
目录文件描述符文件操作的步骤一打开 -- open系统调用1. 函数原型2. 参数详解3. 返回值4. 主要 flags参数详解二读文件 -- read1.函数原型2. 参数详解3. 返回值详解三写入文件 -- write1. 函数原型2. 参数详解3. 返回值详解四文件定位 -- lseek函数1. 函数原型2. 功能3. 参数详解4. whence参数5. 返回值详解6. 关键特性和用法核心使用要点与注意事项系统调用操作系统为了方便用户使用系统功能而对外提供的一组系统函数。关于文件操作的相关函数叫文件io。C库函数c标准库函数c语言程序能够运行的地址默认c库函数都可以调用。 关于文件操作的相关函数叫标准io。标准io和文件io关系文件描述符定义文件描述符是一个非负整数是 Linux 内核用来标识进程打开文件的索引。可以把它理解为文件在特定进程内的“代号”或“编号”。核心特点进程私有每个进程都有自己独立的文件描述符表用于管理本进程打开的所有文件。分配规则文件描述符从0开始顺序分配。标准描述符0、1、2是系统为每个进程预留的三个标准描述符通常关联到终端0 -STDIN_FILENO标准输入默认为键盘。1 -STDOUT_FILENO标准输出默认为屏幕。2 -STDERR_FILENO标准错误输出默认为屏幕。新文件描述符新打开的文件其描述符从3开始分配。文件操作的步骤一打开 --open系统调用1. 函数原型int open(const char *pathname, int flags, mode_t mode);2. 参数详解参数含义说明pathname文件路径需要打开或创建的文件路径字符串。flags打开标志控制文件的打开/创建方式。多个标志用按位或 (\|) 组合。mode权限模式指定新创建文件的访问权限八进制数如0644仅在flags包含O_CREAT时有效。3. 返回值情况返回值成功返回一个非负整数即新打开文件的文件描述符。失败返回-1并设置全局变量errno以指示具体错误。4. 主要flags参数详解flags参数用于指定文件的打开方式是控制open行为的关键。man fopen可以查到这张表标志名称功能与影响O_RDONLY只读打开文件只能用于读取不能写入。O_WRONLY只写打开文件只能用于写入不能读取。O_RDWR读写打开文件既可以读取也可以写入。O_CREAT创建文件如果pathname指定的文件不存在则创建它。需要配合mode参数。O_TRUNC截断文件如果文件已存在且以可写方式 (O_WRONLY或O_RDWR) 打开则将其长度截断为0清空内容。O_APPEND追加模式每次执行write操作时文件偏移量会自动移动到文件末尾保证写入的内容总是被追加到文件尾部。组合使用示例open(“file.txt”, O_RDONLY);// 以只读方式打开已存在的文件open(“log.txt”, O_WRONLY \| O_CREAT \| O_APPEND, 0644);// 以只写、追加模式打开文件不存在则创建权限为rw-r--r--open(“temp.dat”, O_RDWR \| O_CREAT \| O_TRUNC, 0666);// 以读写方式打开文件不存在则创建存在则清空权限为rw-rw-rw-二读文件 -- read1.函数原型ssize_t read(int fd, void *buf, size_t count);2. 参数详解参数数据类型含义与说明fdint文件描述符标识要读取的已打开文件。bufvoid *缓冲区指针指向一片用户空间的内存区域用于存放从文件中读取到的数据。countsize_t请求读取的字节数表示本次希望从文件中最多读取多少个字节到buf中。3. 返回值详解返回值含义与说明 0成功返回实际读取到的字节数。此值可能小于count参数原因包括文件剩余字节不足、从管道或终端读取、被信号中断等。 0表示已到达文件末尾没有更多数据可读。-1失败表示发生了错误。此时会设置全局变量errno以指示具体错误原因如EINTR被信号中断EBADF文件描述符无效等。三写入文件 -- write1. 函数原型ssize_t write(int fd, const void *buf, size_t count);2. 参数详解参数数据类型含义与说明fdint文件描述符标识要写入的已打开文件。bufconst void *数据缓冲区指针指向一片用户空间的内存区域其中包含要写入文件的数据。countsize_t请求写入的字节数表示希望从buf中取出多少个字节写入文件。3. 返回值详解返回值含义与说明 0成功返回实际写入的字节数。在大多数情况下此值等于count。但如果磁盘空间不足、写入被信号中断、或遇到资源限制如 RLIMIT_FSIZE此值可能小于count。 0通常表示没有写入任何数据。对于普通文件这很少见但对于某些特殊文件如管道、套接字可能存在。-1失败表示发生了错误。此时会设置全局变量errno以指示具体错误原因如EINTR被信号中断ENOSPC设备无剩余空间EBADF文件描述符无效等。实现cp功能#include stdio.h #include unistd.h #include fcntl.h int main(int argc, const char *argv[]) { if(argc ! 3) { printf(%s filename filename\n,argv[0]); return -1; } int fd open(argv[1],O_RDONLY|O_CREAT,0666); int fd2 open(argv[2],O_WRONLY|O_CREAT,0666); if(fd 0 || fd2 0) { perror(open fail); return -1; } char buf[1024]; int ret 0; while((ret read(fd,buf,sizeof(buf)))!0) { //buf[ret] \0; // 添加字符串结束符 //printf(ret %d buf %s\n, ret, buf); write(fd2,buf,ret); } return 0; }四文件定位 --lseek函数1. 函数原型#include unistd.h #include sys/types.h off_t lseek(int fd, off_t offset, int whence);2. 功能用于移动文件的读写位置指针实现随机访问。可以读取或写入文件的任意位置而不仅限于顺序从头到尾。3. 参数详解参数数据类型含义与说明fdint文件描述符标识已打开、可定位的文件。offsetoff_t偏移量表示相对于whence指定起点的移动字节数。-正值向文件末尾方向移动向后。-负值向文件开头方向移动向前。whenceint起始位置参考点。决定offset的计算基准是一个整型常量。4.whence参数whence参数通常由以下三个宏定义指定它们是整数常量决定了偏移的起点。宏常量值常见含义与计算基准SEEK_SET0文件开头。从文件开始位置计算偏移。新的偏移量 offset。SEEK_CUR1当前位置。从当前读写指针位置计算偏移。新的偏移量 当前偏移 offset。SEEK_END2文件末尾。从文件结束位置计算偏移。新的偏移量 文件大小 offset。5. 返回值详解返回值含义与说明 0成功返回移动后新的文件偏移量从文件开头算起的字节数。(off_t)-1失败返回-1并设置errno以指示错误如EBADF描述符无效ESPIPE文件不支持定位。重要提示返回值是新的偏移量这是一个非负的、从文件开头计算的字节偏移。即使使用SEEK_CUR或SEEK_END并传入负的offset移动到文件开头之前也会返回-1表示错误而不会成功返回一个负的偏移量。6. 关键特性和用法特性/用法说明与示例获取当前偏移off_t curr_pos lseek(fd, 0, SEEK_CUR);偏移量为0从当前位置计算即返回当前偏移量移动到文件开头lseek(fd, 0, SEEK_SET);移动到文件末尾off_t end_pos lseek(fd, 0, SEEK_END);常用于获取文件大小或为追加写做准备向前/向后移动lseek(fd, 100, SEEK_CUR);// 从当前位置向后移动100字节lseek(fd, -50, SEEK_CUR);// 从当前位置向前移动50字节创建文件空洞如果移动的位置超过了当前文件大小然后执行write操作会在原文件末尾和新写入位置之间形成“空洞”。这部分不占用实际磁盘块读起来是0但会使文件大小增加。核心使用要点与注意事项要点read函数write函数数据流向从文件 (fd) →内存 (buf)从内存 (buf) →文件 (fd)缓冲区管理调用前必须确保buf指向的内存空间足够大至少可容纳count字节。调用前必须确保buf指向的内存区域已包含有效数据。阻塞行为在默认阻塞模式下如果文件中无足够数据如从管道、终端或网络套接字读调用会阻塞直到有数据可读或到达文件尾。在默认阻塞模式下如果由于设备繁忙等原因无法立即写入如向管道写但缓冲区满调用会阻塞直到可以写入。典型用法通常与循环结合使用以处理“实际读取字节数小于请求字节数”的情况确保读取完整数据。通常也应检查返回值在写入大型数据块时可能需要多次调用write以确保所有数据被写入。与标准描述符fd可以为0(STDIN_FILENO)从标准输入读取。fd可以为1(STDOUT_FILENO) 或2(STDERR_FILENO)分别向标准输出或标准错误输出写入。