当前位置: 首页 > news >正文

文件系统常见函数

write系统调用

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);

参数说明

  • fd 文件描述符,指向已打开的文件或设备(如标准输出 1、文件句柄等

  • buf 指向待写入数据的缓冲区指针,支持任意数据类型(如字符数组,结构体等)

  • count 指定需要写入的字节数(从buf中读取的最大的长度)

返回值

  • 成功时‌ 返回实际写入的字节数(可能小于 count,如磁盘空间不足或管道缓冲区满)‌。

  • 失败时‌ 返回 -1,并通过全局变量 errno 标识具体错误类型(如权限不足、文件未打开等)‌

#include <unistd.h>  // 包含系统调用相关函数(如 write)
#include <stdlib.h>  // 包含 exit 函数int main()
{// 向文件描述符 1(标准输出)写入 18 字节数据if ((write(1, "Here is some data\n", 18)) != 18)// 若实际写入字节不等于 18,向文件描述符 2(标准错误)输出错误信息write(2, "A write error has occurred on file descriptor 1\n", 46);exit(0);  // 无论是否出错,都以状态码 0 退出
}

read系统调用

#include <unistd.h>  // 提供 read/write 系统调用
#include <stdlib.h>  // 提供 exit 函数int main() {char buffer[128];    // 定义 128 字节的输入缓冲区int nread;           // 存储 read 的返回值// 从标准输入(fd=0)读取最多 128 字节到 buffernread = read(0, buffer, 128);// 处理读取错误if (nread == -1)write(2, "A read error has occurred\n", 26); // 向标准错误(fd=2)输出// 将读取的数据写入标准输出(fd=1)if ((write(1, buffer, nread)) != nread)write(2, "A write error has occurred\n", 27); // 处理写入错误exit(0); // 程序退出
}

核心逻辑流程‌ 1.数据读取‌

  • 通过 read(0, buffer, 128) 从标准输入(如键盘、管道或重定向文件)读取数据

  • 返回实际读取的字节数 nread(可能小于 128)

  • 返回 -1 表示读取失败(如无权限、中断等)

2.错误处理‌

  • ‌读取错误‌:若 nread == -1,向标准错误输出提示

  • ‌写入错误‌:若实际写入字节数不等于 nread(如磁盘满、管道破裂等),输出错误信息

3.‌数据转发‌

  • 将缓冲区内容通过 write(1, buffer, nread) 原样写入标准输出(如终端屏幕或重定向文件)

open 系统调用详解


1. 基本概念与作用
  • 功能定义open 是Linux文件操作的核心系统调用,用于打开或创建文件,返回唯一的文件描述符(非负整数),供后续read/write等操作使用‌12。

  • 与库函数对比‌ 区别于标准I/O库的fopenopen是底层无缓冲操作,直接操作文件描述符而非文件流‌

#include <fcntl.h>
#include <sys/stat.h>int open(const char *pathname, int flags);          // 基础形式
int open(const char *pathname, int flags, mode_t mode);  // 创建文件时需指定权限- pathname文件路径(绝对或相对)"/home/user/file.txt"flags控制打开方式和行为的标志位(必选参数)O_RDWR | O_CREAT | O_APPENDmode新文件权限(仅当flags含O_CREAT时有效)0644(rw-r--r--)O_RDONLY:只读
O_WRONLY:只写
O_RDWR:读写//O_CREAT	 文件不存在时创建新文件(需配合mode参数)
//O_EXCL 	与O_CREAT联用,若文件存在则返回错误(用于原子性创建)
//O_TRUNC 	打开时清空文件内容(仅对普通文件有效)
//O_APPEND 	写操作前自动定位到文件末尾(避免并发写入覆盖)
//O_NONBLOCK 非阻塞模式打开(适用于管道、设备文件等)

close统调用详解

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

一个文件复制程序

#include <unistd.h>    // 提供 read/write/open 系统调用
#include <sys/stat.h>  // 提供文件权限宏(如 S_IRUSR)
#include <fcntl.h>     // 提供文件打开标志(如 O_RDONLY)
#include <stdlib.h>    // 提供 exit 函数int main(){char c;            // 单字节缓冲区int in, out;       // 输入/输出文件描述符// 打开输入文件(只读模式)in = open("file.in", O_RDONLY);// 打开输出文件(写入模式,不存在则创建,权限:用户可读可写)out = open("file.out", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);// 逐字节读取输入文件while (read(in, &c, 1) == 1) {// 将字节写入输出文件write(out, &c, 1);}exit(0);  // 程序退出(未显式关闭文件描述符)
}
核心逻辑与流程
  1. 打开文件
    • file.in:以只读模式打开(若不存在则失败)

    • file.out:以写入模式打开,不存在时创建,权限为 0600(用户可读写)

  2. 数据复制

    • 每次读取 1 字节到变量 c

    • c 写入目标文件(每次 1 字节)

  3. 终止程序

    • 通过 exit(0) 退出,未显式关闭文件描述符(由内核自动处理)

#include <unistd.h>   // 系统调用:read/write/open/close
#include <sys/stat.h> // 文件权限宏(S_IRUSR等)
#include <fcntl.h>    // 文件打开标志(O_RDONLY等)
#include <stdlib.h>   // exit函数int main() {char block[1024]; // 缓冲区(1KB)int in, out;      // 输入/输出文件描述符int nread;        // 实际读取的字节数// 打开输入文件(只读模式)in = open("file.in", O_RDONLY);// 打开输出文件(写入模式,不存在则创建,权限:用户可读可写)out = open("file.out", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);// 循环读取输入文件到缓冲区while ((nread = read(in, block, sizeof(block))) > 0) {// 将缓冲区内容写入输出文件write(out, block, nread);}exit(0); // 退出程序(未显式关闭文件描述符)
}

fopen函数

FILE *fopen(const char *filename, const char *mode);
//filename 文件路径字
//mode 文件打开模式
#include <stdio.h>int main() {FILE *fp = fopen("data.txt", "r");  // 以只读模式打开文件if (fp == NULL) {perror("文件打开失败");         // 输出错误信息(如 "No such file or directory")return 1;}// 文件操作...fclose(fp);                         // 关闭文件流return 0;
}

fread函数

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

参数解析‌

  • ‌ptr‌:指向存储读取数据的内存缓冲区的指针(需预先分配足够空间)‌

  • ‌size‌:每个数据项的字节大小(例如 sizeof(int) 或 sizeof(struct))‌

  • ‌nmemb‌:要读取的数据项数量‌

  • ‌stream‌:指向已打开的文件的 FILE 指针(需通过 fopen 打开)‌

‌返回值‌

  • 成功时返回 ‌实际读取的数据项数量‌(若小于 nmemb,可能因文件结束或错误)‌

  • ‌返回0‌ 表示读取失败或到达文件末尾‌

#1.打开文件流
FILE *fp = fopen("data.bin", "rb");  // 以二进制只读模式打开文
if (fp == NULL) {perror("文件打开失败");exit(EXIT_FAILURE);
}#2.分配缓冲区
int buffer[100];#3.调用fread函数
size_t num_read = fread(buffer, sizeof(int), 100, fp);
if (num_read < 100) {if (feof(fp))  // 检查是否到达文件末printf("已读取到文件末尾,实际读取数量:%zu\n", num_read);else if (ferror(fp))  // 检查是否发生错perror("读取错误");
}

fwrite函数

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

‌参数说明‌:

  • ptr:指向待写入数据的缓冲区首地址(如数组、结构体或动态分配的内存块)‌

  • size:单个数据项的字节大小(通常用 sizeof() 运算符获取,如 sizeof(int))‌

  • nmemb:要写入的数据项数量(例如数组元素个数)‌

  • stream:目标文件指针,需通过 fopen 以二进制模式(如 "wb"、"ab")打开‌

‌返回值‌:

  • 成功时返回实际写入的数据项数量(非字节数)‌

  • 若返回值小于 nmemb,需用 ferror() 检查错误或 feof() 判断是否到达文件末尾‌

    示例1:写入字符串
#include <stdio.h>int main() {FILE *fp;if (fopen_s(&fp, "text.txt", "wb") != 0) {  // 以二进制模式写perror("文件打开失败");return -1;}char buffer[] = "Hello, fwrite!";size_t written = fwrite(buffer, sizeof(char),sizeof(buffer), fp);fclose(fp);return 0;
}
#示例2:写入结构体数组
typedef struct {int id;float score;
} Student;int main() {Student students[] = {{1, 90.5}, {2, 85.0}};FILE *fp = fopen("students.dat", "wb");if (!fp) {perror("文件打开失败");return 1;}size_t num_written = fwrite(students, sizeof(Student), 2, fp);fclose(fp);return 0;
}

fclose函数

int fclose(FILE *stream);  
  • 参数‌:streamfopenfreopen 返回的文件指针,指向需要关闭的文件流‌。

  • ‌返回值

    • 成功‌:返回 0‌。

    • 失败‌:返回 EOF(通常为 -1),需检查 errno 获取具体错误原因(如 EINVAL 表示参数无效)‌。


2. 核心功能
  • 关闭文件流‌:释放文件占用的系统资源,解除文件指针与底层文件的关联‌23。

  • 刷新缓冲区‌:将缓冲区中未写入的数据同步到磁盘,确保数据完整性‌


3. 使用步骤
  1. 检查文件指针有效性

FILE *fp = fopen("data.txt", "r");  
if (fp == NULL) {  perror("文件打开失败");  exit(EXIT_FAILURE);  
}  

     2.操作文件‌(如读写)后调用 fclose

// 文件读写操作...  
int ret = fclose(fp);  
if (ret != 0) {  perror("关闭文件失败");  
}  

fflush函数

int fflush(FILE *stream);  
  • 参数

    • stream:指向 FILE 类型指针,标识需刷新的文件流(如 stdoutstderr 或已打开的文件指针)‌。

    • streamNULL,则刷新所有已打开的‌输出流‌的缓冲区‌。

  • ‌返回值

    • 成功‌:返回 0‌。

    • 失败‌:返回 EOF,并通过 ferror() 检查错误原因(如磁盘空间不足或流未打开)‌。


2. 核心功能
  • 刷新输出流缓冲区‌:强制将缓冲区中未写入的数据立即同步到文件或设备(如磁盘、终端)‌。

  • ‌适用场景:

    1. 确保关键数据在程序崩溃前持久化(如日志文件)‌。

    2. 交互式程序需即时显示输出(如进度条或调试信息)‌。

    3. 多线程环境下避免缓冲区竞争‌。


3. 使用示例

示例 1:强制刷新 stdout

#include <stdio.h>  
int main() {  printf("正在加载...");  fflush(stdout);  // 立即输出,无需等待换行符  // 耗时操作...  printf("完成\n");  return 0;  
}  

示例 2:刷新文件流

FILE *fp = fopen("data.txt", "w");  
if (fp) {  fprintf(fp, "重要数据");  fflush(fp);  // 确保数据写入磁盘  // 其他操作...  fclose(fp);  
}  

fseek函数

fseek 是 C 语言标准库中用于控制文件指针位置的核心函数,支持文件的随机访问操作。以下是其核心要点:

int fseek(FILE *stream, long offset, int origin);  
  • ‌stream‌:指向已打开文件的指针,需确保文件支持定位操作(如 r+、w+ 模式)‌

  • ‌offset‌:相对于 origin 的偏移量(单位:字节),可为正(向后偏移)或负(向前偏移)‌

  • ‌origin‌:基准位置,可选常量:

    • SEEK_SET(文件开头)

    • SEEK_CUR(当前位置)

    • SEEK_END(文件末尾)‌

‌2. 返回值与功能‌
  • ‌功能‌:重新定位文件指针到 origin + offset 的位置,突破顺序读写的限制‌

  • ‌返回值‌:成功返回 0,失败返回非零值(通常为 -1)‌

‌3. 核心应用场景‌
  • ‌随机读写‌:直接跳转到文件任意位置读写数据(如修改文件中间部分内容)‌

  • ‌二进制文件操作‌:精准定位数据块(如读取结构体数组中的特定元素)‌

  • ‌结合其他函数‌:

    • 与 ftell 配合获取当前指针位置‌

    • 与 rewind 等效于 fseek(stream, 0, SEEK_SET)

‌4. 示例代码

#include <stdio.h>  
int main() {  FILE *fp = fopen("data.txt", "r+");  if (fp == NULL) {  perror("Error opening file");  return 1;  }  // 跳转到第 4 个字节(从文件开头)  fseek(fp, 3, SEEK_SET);  char ch = fgetc(fp);  // 读取第四个字符  printf("Character at position 3: %c\n", ch);  fclose(fp);  return 0;  
}  

fgetc,getc和getchar函数

‌1. 函数原型与定义‌

‌fgetc‌
int fgetc(FILE *stream); 

从指定文件流(如文件指针或 stdin)读取单个字符,返回 int 类型的字符值(无符号字符转换为 int)或 EOF(错误或文件末尾)‌

getc‌
int getc(FILE *stream)
  • 功能与 fgetc 完全相同,但通常以宏实现,执行效率更高(编译时直接展开代码)‌

  • ‌注意‌:若参数 stream 是表达式(如 getc(fp++)),可能导致未定义行为(宏参数被多次求值)‌

    getchar‌
int getchar(void)

等同于 getc(stdin),专用于从标准输入(键盘)读取字符‌

‌2. 核心区别‌

  • . 共同点与返回值‌

  • ‌返回值‌:

    • 成功时返回读取的字符(转换为 int),失败或文件末尾返回 EOF‌

    • 需通过 feof() 或 ferror() 区分错误类型(如磁盘错误 vs 文件结束)‌

  • ‌缓冲区行为‌:

    均从输入缓冲区读取数据,若缓冲区为空则等待用户输入(如键盘输入需按回车键触发读取)‌

#1.fgetc读取文件
FILE *fp = fopen("data.txt", "r");  
if (fp) {  int c; //fgetc读取单个字符 while ((c = fgetc(fp)) != EOF) {  putchar(c);  }  fclose(fp);  
}  #2.getc高效读取
FILE *fp = fopen("log.txt", "r");  
if (fp) {  int c = getc(fp);  // 宏展开,无函数调用开销  // 处理字符...  fclose(fp);  
}  #getchar读取键盘输入
printf("输入一个字符:");  
int c = getchar();  // 等同于 getc(stdin)  
if (c != EOF) {  printf("你输入的是:%c\n", c);  
}  

文件和目录访问权限

chmod函数调用详解

chmod 是 Linux/Unix 系统中用于修改文件权限的系统调用函数,通过指定路径或文件描述符调整文件的访问权限。以下是其核心要点及用法:

1.函数原型与参数

#include <sys/stat.h>  
int chmod(const char *pathname, mode_t mode);  // 基于路径修改权限
int fchmod(int fd, mode_t mode);               // 基于文件描述符修改权限
  • pathname‌:目标文件路径(相对或绝对路径)。

  • ‌fd‌:已打开文件的描述符(需确保文件已通过 open 等函数打开)。

  • ‌mode‌:权限模式值,通常为八进制数(如 0644)或宏组合(如 S_IRUSR | S_IWGRP)‌

#include <stdio.h>  
#include <sys/stat.h>  
#include <stdlib.h>  int main() {  const char *filename = "test.txt";  int res = chmod(filename, 0644);  // 修改为用户可读写,组和其他用户只读  if (res == -1) {  perror("chmod failed");       // 输出错误信息(如权限不足)  exit(1);  }  printf("权限修改成功\n");  return 0;  
}  

chown 函数调用详解

chown 是 Linux/Unix 系统中用于修改文件所有者(用户 ID)和所属组(组 ID)的系统调用函数,支持通过路径或文件描述符操作。以下是其核心要点及用法:

#include <unistd.h>  
int chown(const char *pathname, uid_t owner, gid_t group);  // 基于路径修改属主  
int fchown(int fd, uid_t owner, uid_t group);               // 基于文件描述符修改属主  
int lchown(const char *pathname, uid_t owner, gid_t group);  // 修改符号链接本身的属主  
#include <unistd.h>  
#include <stdio.h>  int main() {  const char *filename = "test.txt";  uid_t new_owner = 1000;  // 用户 ID(通过 /etc/passwd 查询)  gid_t new_group = 1000;  // 组 ID(通过 /etc/group 查询)  if (chown(filename, new_owner, new_group) == -1) {  perror("chown failed");  return 1;  }  printf("文件属主修改成功\n");  return 0;  
}  

opendir函数

opendir 是 Linux/Unix 系统中用于打开目录的标准库函数,属于目录操作的核心 API,需结合 readdir 和 closedir 实现目录遍历。以下是其关键知识点及用法:

#include <sys/types.h>  
#include <dirent.h>  
DIR *opendir(const char *name);  
  • 参数 name‌:需打开的目录路径(绝对或相对路径),需以 \0 结尾的字符串形式传入‌

  • 返回值‌

    • 成功:返回 DIR* 类型的目录流指针,用于后续操作(如读取目录项)‌

    • 失败:返回 NULL,并设置 errno 标识具体错误‌

使用流程与示例‌

步骤‌:

1.调用 opendir 打开目录并获取 DIR* 流指针。

2.使用 readdir 逐项读取目录内容。

3.操作完成后调用 closedir 关闭目录流‌

#include <dirent.h>  
#include <stdio.h>  int main() {  DIR *dir = opendir(".");  // 打开当前目录if (dir == NULL) {  perror("opendir failed");  return 1;  }  struct dirent *entry;  while ((entry = readdir(dir)) != NULL) {  // 遍历目录项  printf("文件名: %s\n", entry->d_name);  }  closedir(dir);  // 关闭目录流  return 0;  
}  
注意事项‌
  • ‌资源管理‌:必须显式调用 closedir 释放目录流,避免资源泄漏‌

  • ‌符号链接‌:opendir 默认跟随符号链接打开目标目录,若需操作链接自身需结合其他函数(如 lstat)‌

  • ‌并发安全‌:目录内容在遍历过程中可能被其他进程修改,需注意竞态条件‌

代码解析‌
1.‌struct dirent结构体定义‌
  • struct dirent 是系统预定义的目录项结构体,用于存储单个目录项(文件或子目录)的信息‌

  • 其典型成员包括:

struct dirent {  ino_t d_ino;       // 文件的 inode 编号  char d_name[256];  // 文件名(以 \0 结尾的字符串)  // 其他成员可能因系统不同而异(如 d_type、d_reclen 等)  
};  
‌2.指针声明‌
  • entry 是一个指向 struct dirent 的指针变量,用于接收 readdir() 函数返回的目录项数据‌

  • 通过该指针可访问当前遍历项的文件名、inode 等信息,例如:

printf("文件名: %s\n", entry->d_name);   // 输出当前文件
printf("inode: %lu\n", entry->d_ino);    // 输出当前文件的 inod
3.‌典型使用场景

结合 opendirreaddirclosedir 实现目录遍历:

#include <dirent.h>  
DIR *dir = opendir(".");               // 打开当前目录
struct dirent *entry;  
while ((entry = readdir(dir)) != NULL) {  // 逐项读取目录内容// 处理 entry 指向的目录项  
}  
closedir(dir);                          // 关闭目录
  • readdir 的作用‌:每次调用返回下一个目录项的指针,遍历完成或出错时返回 NULL

‌注意事项‌
  • ‌内存管理‌:entry 指针指向的内存由 readdir 函数内部管理,无需手动释放‌

  • ‌线程安全‌:readdir 非线程安全,多线程环境需用 readdir_r‌

  • ‌隐藏文件‌:遍历结果包含 .(当前目录)和 ..(上级目录),需根据业务过滤‌

readdir 函数详解

readdir 是 Linux/Unix 系统中用于遍历目录内容的核心函数,需与 opendir 和 closedir 配合使用。以下是其核心知识点及用法:

‌1. 函数原型与头文件
#include <dirent.h>  
struct dirent *readdir(DIR *dirp);  
  • 参数 dirp‌:由 opendir 返回的目录流指针指向待遍历的目录‌

  • 返回值‌:

    • 成功:返回指向 struct dirent 的指针,包含当前目录项信息‌

    • 失败/遍历结束:返回 NULL(若出错,需检查 errno)‌

‌2. struct dirent 结构体成员‌

struct dirent 用于存储目录项信息,关键成员包括:

struct dirent {  ino_t d_ino;           // 文件的 inode 编  char d_name[256];      // 文件名(以 `\0` 结尾的字符串unsigned char d_type;  // 文件类型(如 DT_REG 普通文件,DT_DIR 目录// 其他字段如 d_reclen(记录长度)、d_off(偏移量)可能因系统不同而存
};  
#注:d_name 是标准必用字段,d_type 非所有系统都支持‌
3.典型使用流程
#include <dirent.h>  
DIR *dir = opendir(".");          // 打开当前目录
struct dirent *entry;  
while ((entry = readdir(dir)) != NULL) {  printf("文件名: %s\n", entry->d_name);  // 输出文件名‌  if (entry->d_type == DT_REG) {  printf("普通文件\n");  }  
}  
closedir(dir);                    // 关闭目录流‌

entry->d_name 代码解析‌

entry->d_name 是 C 语言中用于访问目录项名称的语法,其核心含义和用途如下:

‌1. 定义与数据结构‌
  • entry 是 struct dirent 类型的指针,指向由 readdir() 函数读取的目录项信息‌

  • d_name 是 struct dirent 结构体的成员变量,用于存储文件名(或子目录名),类型为 char[256] 的字符数组,以 \0 结尾‌

‌2. 典型用途‌
  • 获取文件名‌:通过 entry->d_name 可获取当前遍历到的文件或子目录的名称,例如:

  • while ((entry = readdir(dir)) != NULL) {  printf("文件名: %s\n", entry->d_name);  // 输出当前文件/子目录名称‌
    }  

    过滤特殊目录项:在遍历目录时,通常需跳过 .(当前目录)和 ..(上级目录):

if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {  continue;  // 跳过特殊目录项‌  
}  
  • 与其他函数配合‌:结合 stat()lstat() 函数获取文件详细信息:

struct stat file_info;  
lstat(entry->d_name, &file_info);  // 根据文件名获取元数据
‌3. 注意事项‌

‌数据类型限制‌:d_name 仅存储名称,不包含路径信息。需手动拼接路径(如 snprintf(path, sizeof(path), "%s/%s", dir_path, entry->d_name);)‌ ‌跨平台兼容性‌:d_name 是标准字段,在所有支持 POSIX 的系统(如 Linux、Unix)中可用‌

stat()lstat() 函数详解

stat()lstat() 是 Linux/Unix 系统中用于获取文件元数据的核心函数,需包含头文件 <sys/stat.h><sys/types.h>。以下为关键知识点及用法总结:

1.函数原型与区别
int stat(const char *pathname, struct stat *buf);     // 通过路径获取文件信息‌
int lstat(const char *pathname, struct stat *buf);    // 针对符号链接返回链接本身信息(而非目标文件)

参数 pathname‌:文件或目录的路径。  

•  ‌参数 buf‌:存储文件属性的 struct stat 结构体指针‌

 •  ‌返回值‌:成功返回 0,失败返回 -1 并设置 errno‌   ‌

核心区别‌:

•  stat() 对符号链接会解析到目标文件,而 lstat() 仅获取链接自身的属性‌

2.struct stat 结构体成员

&file_stat  

&file_stat 是 C 语言中用于获取 struct stat 类型变量地址的语法,其核心作用如下: ‌

1. 语法解析与用途‌

•  ‌取地址运算符‌:& 运算符用于获取变量 file_stat 的内存地址‌  

•  ‌配合系统函数‌:stat()、lstat() 等函数需通过指针参数写入文件属性数据,因此需将 file_stat 的地址传递给函数‌  

示例:

struct stat file_stat;  
stat("test.txt", &file_stat);  // &file_stat 作为指针参数传入函数‌
‌2. 关键知识点‌

•  ‌函数参数要求‌:stat() 函数的第二个参数类型为 struct stat *(指向结构体的指针),必须传递地址而非变量本身‌  

•  ‌数据写入机制‌:函数内部通过指针直接修改 file_stat 的内存,无需返回值即可保存文件属性信息‌  

‌telldir 函数详解‌ ‌

1. 功能与定义‌

telldir() 用于获取目录流的‌当前位置偏移量‌,返回值表示距离目录文件开头的偏移值,常用于与 seekdir() 配合实现目录遍历的断点续扫‌

•  ‌函数原型‌:        

 #include <dirent.h>   
long int telldir(DIR *dirp);  // Linux 标准定义• 
off_t telldir(DIR *dirp);     // 部分系统使用 off_t 类型•      
  • 参数‌:dirp 为 opendir() 打开的目录流指针。
  •  返回值‌:  
  • 成功:返回当前偏移量(长整型或 off_t 类型)。  
  • 失败:返回 -1,并设置 errno 为 EBADF(目录流无效)‌
  ‌2. 核心应用场景‌

1.  ‌目录遍历状态保存‌
在遍历目录时记录偏移量,便于后续通过 seekdir() 恢复至指定位置,避免重复扫描‌

DIR *dir = opendir("/path");  
struct dirent *entry;  
long pos;  
while ((entry = readdir(dir)) != NULL) {  pos = telldir(dir);  // 记录当前偏移量‌// 处理 entry  
}  
seekdir(dir, pos);       // 恢复到最后记录的位置‌

entry 是一个指向 struct dirent 的指针变量,用于接收 readdir() 函数返回的目录项数据‌

seekdir 函数详解‌

1. 功能与定义‌

seekdir() 用于设置目录流的读取位置,允许通过指定偏移量跳转至目录项的特定位置,常与 telldir() 配合实现断点续扫或随机访问目录内容‌

函数原型‌:
#include <dirent.h>  
void seekdir(DIR *dirp, off_t offset);  
  • 参数‌:

  • dirp:由 opendir() 打开的目录流指针。

  • offset:目标偏移量,必须为 telldir() 的返回值,否则行为未定义‌

2. 核心应用场景‌

1.恢复目录遍历位置‌ 通过 telldir() 记录偏移量,后续使用 seekdir() 恢复至该位置,适用于中断后继续读取目录的场景‌

DIR *dir = opendir("/path");  
off_t pos = telldir(dir);  // 记录当前偏移量‌:ml-citation{ref="5,7" data="citationList"}  
// ...(其他操作)  
seekdir(dir, pos);          // 恢复至记录位置‌:ml-citation{ref="1,8" data="citationList"}  

‌closedir 函数详解‌

‌1. 功能与定义‌

closedir() 用于关闭由 opendir() 打开的目录流,释放相关系统资源,防止内存泄漏和文件描述符耗尽‌:

#include <sys/types.h> 
#include <dirent.h>  
int closedir(DIR *dirp);  
#include <unistd.h>    // 提供系统调用(如 chdir)
#include <stdio.h>     // 标准输入输出(如 printf)
#include <dirent.h>    // 目录操作(opendir, readdir)
#include <string.h>    // 字符串处理(如 strcmp)
#include <sys/stat.h>  // 文件状态(stat, lstat)
#include <stdlib.h>    // 标准库函数(如 exit)/*dir:当前要遍历的目录路径* depth:缩进深度,用于展示层级结构*/
void printdir(char *dir, int depth)
{DIR *dp;struct dirent *entry;struct stat statbuf;1.打开目录/*尝试打开目录,失败则报错返回。*/if((dp = opendir(dir)) == NULL) {fprintf(stderr,"cannot open directory: %s\n", dir);return;}2.进入目录chdir(dir);//切换到目标目录,以便处理其内部条目。3.遍历目录whiile((entry = readdir(dp)) != NULL) {//readdir:逐个读取目录中的条目(文件或子目录)。//lstat:获取条目的元数据(如文件类型)lstat(entry->d_name,&statbuf);4.处理子目录S_ISDIR  系统定义的宏  通过解析st_mode的二进制判断文件是否为目录statbuf.st_mode 属于struct stat结构体if(S_ISDIR(statbuf.st_mode)) {/* Found a directory, but ignore . and .. */if(strcmp(".",entry->d_name) == 0 ||strcmp("..",entry->d_name) == 0)continue;printf("%*s%s/\n",depth,"",entry->d_name);/* Recurse at a new indent level */printdir(entry->d_name,depth+4); //递归处理子目录}else printf("%*s%s\n",depth,"",entry->d_name);}chdir("..");closedir(dp);
} 

opendir() 打开目录流,返回 DIR* 指针。

readdir() 读取目录中的下一个条目,返回 struct dirent(包含文件名 d_name)。

lstat() 获取文件元数据(如类型、权限),避免解引用符号链接。

S_ISDIR(st_mode) 宏:检查条目是否为目录。

chdir() 切换当前工作目录。

相关文章:

  • 2022 年 9 月青少年软编等考 C 语言七级真题解析
  • 根据定义给出json_schema:
  • 【Python】每隔一段时间自动清除网站上cookies的方法
  • 使用 Streamlit 打造一个简单的照片墙应用
  • 极狐GitLab 的压缩和合并是什么?
  • sglang部署DeepSeek-R1-Distill-Qwen-7B
  • fpga系列 HDL:跨时钟域同步 脉冲展宽同步 Pulse Synchronization
  • 四神-华夏大地的守护神
  • 今天开始着手准备PAT(乙级)
  • 第一节:核心概念高频题-Vue3响应式原理与Vue2的区别
  • MYSQL之表的操作
  • 在面试中被问到spring是什么?
  • Kubernetes Multus CNI详细剖析
  • 渗透测试中的信息收集:从入门到精通
  • 爬虫学习总结
  • 滑动窗口算法(一)
  • Transformer起源-Attention Is All You Need
  • Sql文件处理SQLDumpSplitter
  • git lfs下载大文件限额
  • 按照文本每行匹配文件复制到指定位置
  • 央行上海总部答澎湃:上海辖内金融机构已审批通过股票回购增持贷款项目117个
  • 新东方:2025财年前三季度净利增29%,第四财季海外业务将承压
  • 驯服象牙塔:美国政府对大学的战争是一场善恶对抗吗
  • 北京朝阳法院:未经许可使用他人剧本语句和情节构成侵权
  • 中国驻日本大使馆发言人就日方涉靖国神社消极动向答记者问
  • 董明珠连任格力电器董事,回应管理层年轻化