文件与目录操作函数详解

在编程中,文件和目录操作是常见的任务。本文将详细讲解常用的文件操作函数和目录操作函数,包括其功能、参数、使用方法,并通过示例代码展示如何用这些函数实现常见的操作。

文件操作函数

1.1 fopen() 函数

功能:打开或创建文件。
参数

  • const char *pathname:文件名。

  • const char *mode:文件操作模式。常见的模式有:

    • "r":只读模式,文件必须存在。

    • "w":只写模式,文件不存在则创建,存在则清空。

    • "a":追加模式,文件不存在则创建,存在则从末尾开始写入。
      返回值

  • 成功返回一个 FILE * 类型的文件指针。

  • 失败返回 NULLerrno 会被设置。
    示例代码

#include 
int main() {
    FILE *fp = fopen("example.txt", "r");
    if (fp == NULL) {
        perror("fopen failed");
        return -1;
    }
    fclose(fp);
    return 0;
}

解释

  • fopen("example.txt", "r"):尝试以只读模式打开名为 "example.txt" 的文件。

  • 如果文件不存在或无法打开,fopen 将返回 NULL,程序通过 perror 输出错误信息。

  • 最后调用 fclose(fp) 关闭文件。

1.2 fclose() 函数

功能:关闭文件指针。
参数

  • FILE *fp:要关闭的文件指针。
    返回值

  • 成功返回 0

  • 失败返回 EOF
    示例代码

fclose(fp); // 关闭文件

解释

  • fclose(fp):关闭文件指针 fp,释放与文件相关的系统资源。

1.3 fgetc() 函数

功能:从文件指针中读取一个字符。
参数

  • FILE *fp:文件指针。
    返回值

  • 成功返回读取的字符。

  • 失败或到达文件末尾返回 EOF
    示例代码

char c = fgetc(fp);
if (c == EOF) {
    perror("fgetc failed");
    return -1;
}

解释

  • fgetc(fp):从文件指针 fp 中读取一个字符。

  • 如果读取失败或到达文件末尾,返回值为 EOF,程序通过 perror 输出错误信息。

1.4 fputc() 函数

功能:向文件指针写入一个字符。
参数

  • int c:要写入的字符。

  • FILE *fp:文件指针。
    返回值

  • 成功返回写入的字符。

  • 失败返回 EOF
    示例代码

int ret = fputc('A', fp);
if (ret == EOF) {
    perror("fputc failed");
    return -1;
}

解释

  • fputc('A', fp):向文件指针 fp 写入字符 'A'

  • 如果写入失败,返回值为 EOF,程序通过 perror 输出错误信息。

1.5 fgets() 函数

功能:从文件指针中读取一行数据。
参数

  • char *str:存储读取数据的字符串。

  • int n:最大读取字符数。

  • FILE *fp:文件指针。
    返回值

  • 成功返回读取的字符串。

  • 失败或到达文件末尾返回 NULL
    示例代码

char buffer[100];
char *line = fgets(buffer, sizeof(buffer), fp);
if (line == NULL) {
    perror("fgets failed");
    return -1;
}

解释

  • fgets(buffer, sizeof(buffer), fp):从文件指针 fp 中读取一行数据到缓冲区 buffer 中。

  • 如果读取失败或到达文件末尾,返回值为 NULL,程序通过 perror 输出错误信息。

1.6 fputs() 函数

功能:向文件指针写入一行数据。
参数

  • const char *str:要写入的字符串。

  • FILE *fp:文件指针。
    返回值

  • 成功返回非负值。

  • 失败返回 EOF
    示例代码

int ret = fputs("Hello, World!\n", fp);
if (ret == EOF) {
    perror("fputs failed");
    return -1;
}

解释

  • fputs("Hello, World!\n", fp):向文件指针 fp 写入字符串 "Hello, World!\n"

  • 如果写入失败,返回值为 EOF,程序通过 perror 输出错误信息。

1.7 fscanf()fprintf() 函数

功能:格式化输入输出。

  • fscanf() 从文件指针中读取格式化输入。

  • fprintf() 向文件指针写入格式化输出。
    参数

  • FILE *fp:文件指针。

  • const char *format:格式字符串。
    返回值

  • fscanf() 返回成功读取的输入项数。

  • fprintf() 返回写入的字符数。
    示例代码

int num;
FILE *fp = fopen("data.txt", "r");
if (fp == NULL) {
    perror("fopen failed");
    return -1;
}
fscanf(fp, "%d", &num);
fprintf(stdout, "Read number: %d\n", num);
fclose(fp);

解释

  • fscanf(fp, "%d", &num):从文件指针 fp 中读取一个整数到变量 num 中。

  • fprintf(stdout, "Read number: %d\n", num):向标准输出写入格式化字符串,显示读取的整数。

1.8 rewind() 函数

功能:将文件指针重置到文件开头。
参数

  • FILE *fp:文件指针。
    示例代码

rewind(fp); // 文件指针重置到文件开头

解释

  • rewind(fp):将文件指针 fp 重置到文件开头,方便再次读取文件。

1.9 ftell() 函数

功能:获取文件指针的当前位置。
参数

  • FILE *fp:文件指针。
    返回值

  • 成功返回当前偏移量。

  • 失败返回 -1errno 会被设置。
    示例代码

long offset = ftell(fp);
if (offset == -1) {
    perror("ftell failed");
    return -1;
}

解释

  • ftell(fp):获取文件指针 fp 的当前位置,以文件开头为基准的字节数。

  • 如果失败,返回值为 -1,程序通过 perror 输出错误信息。

1.10 fseek() 函数

功能:重新定位文件指针。
参数

  • FILE *fp:文件指针。

  • long offset:偏移量。

  • int whence:参考点(SEEK_SETSEEK_CURSEEK_END)。
    返回值

  • 成功返回 0

  • 失败返回非零值。
    示例代码

if (fseek(fp, 0, SEEK_END) != 0) {
    perror("fseek failed");
    return -1;
}

解释

  • fseek(fp, 0, SEEK_END):将文件指针 fp 定位到文件末尾。

  • SEEK_END 表示参考点为文件末尾,offset0 表示定位到文件末尾。

1.11 fdopen()fileno() 函数

功能

  • fdopen():将文件描述符转换为文件指针。

  • fileno():将文件指针转换为文件描述符。
    参数

  • fdopen()

    • int fd:文件描述符。

    • const char *mode:打开模式。

  • fileno()

    • FILE *stream:文件指针。
      返回值

  • fdopen() 返回文件指针。

  • fileno() 返回文件描述符。
    示例代码

#include 
#include 
int fd = open("example.txt", O_RDWR);
FILE *fp = fdopen(fd, "r+");
if (fp == NULL) {
    perror("fdopen failed");
    return -1;
}
int fdFromFP = fileno(fp);

解释

  • fdopen(fd, "r+"):将文件描述符 fd 转换为文件指针 fp,打开模式为读写。

  • fileno(fp):将文件指针 fp 转换为文件描述符 fdFromFP

1.12 rename() 函数

功能:重命名或移动文件。
参数

  • const char *oldname:旧文件名。

  • const char *newname:新文件名。
    返回值

  • 成功返回 0

  • 失败返回 -1errno 会被设置。
    示例代码

if (rename("oldfile.txt", "newfile.txt") != 0) {
    perror("rename failed");
    return -1;
}

解释

  • rename("oldfile.txt", "newfile.txt"):将文件 "oldfile.txt" 重命名为 "newfile.txt"

  • 如果失败,返回值为 -1,程序通过 perror 输出错误信息。

1.13 remove() 函数

功能:删除文件。
参数

  • const char *filename:文件名。
    返回值

  • 成功返回 0

  • 失败返回 -1errno 会被设置。
    示例代码

if (remove("file.txt") != 0) {
    perror("remove failed");
    return -1;
}

解释

  • remove("file.txt"):删除文件 "file.txt"

  • 如果失败,返回值为 -1,程序通过 perror 输出错误信息。

1.14 stat()fstat()lstat() 函数

功能:获取文件状态信息。
参数

  • const char *pathname:文件名。

  • struct stat *buf:存储文件状态信息的结构体指针。
    返回值

  • 成功返回 0

  • 失败返回 -1errno 会被设置。
    示例代码

#include 
struct stat buf;
if (stat("example.txt", &buf) == 0) {
    printf("File size: %ld bytes\n", buf.st_size);
} else {
    perror("stat failed");
    return -1;
}

解释

  • stat("example.txt", &buf):获取文件 "example.txt" 的状态信息,并存储在结构体 buf 中。

  • buf.st_size 表示文件的大小(以字节为单位)。

1.15 flock()fcntl() 函数

功能

  • flock():对文件进行加锁。

  • fcntl():对文件描述符进行操作(如加锁)。
    参数

  • int fd:文件描述符。

  • int cmd:操作命令。
    返回值

  • 成功返回 0

  • 失败返回 -1errno 会被设置。
    示例代码

#include 
#include 
int fd = open("example.txt", O_RDWR);
if (fd < 0) {
    perror("open failed");
    return -1;
}
if (flock(fd, LOCK_EX) == 0) {
    // 文件已加锁,可以进行操作
    flock(fd, LOCK_UN); // 解锁
} else {
    perror("flock failed");
    return -1;
}
close(fd);

解释

  • flock(fd, LOCK_EX):对文件描述符 fd 进行独占锁操作。

  • LOCK_EX 表示独占锁。

  • flock(fd, LOCK_UN):解锁文件。

目录操作函数

2.1 opendir() 函数

功能:打开目录。
参数

  • const char *pathname:目录名。
    返回值

  • 成功返回 DIR * 指针。

  • 失败返回 NULLerrno 会被设置。
    示例代码

DIR *dir = opendir("/");
if (dir == NULL) {
    perror("opendir failed");
    return -1;
}

解释

  • opendir("/"):打开目录 /

  • 如果失败,返回值为 NULL,程序通过 perror 输出错误信息。

2.2 readdir() 函数

功能:读取目录项。
参数

  • DIR *dirp:目录指针。
    返回值

  • 成功返回 struct dirent * 指针。

  • 失败或到达目录末尾返回 NULL
    示例代码

struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
    printf("Found entry: %s\n", entry->d_name);
}

解释

  • readdir(dir):读取目录 dir 中的条目,直到到达目录末尾。

  • entry->d_name 表示目录条目的名称。

2.3 closedir() 函数

功能:关闭目录。
参数

  • DIR *dirp:目录指针。
    返回值

  • 成功返回 0

  • 失败返回 -1errno 会被设置。
    示例代码

closedir(dir); // 关闭目录

解释

  • closedir(dir):关闭目录指针 dir,释放相关资源。

2.4 chdir() 函数

功能:改变当前工作目录。
参数

  • const char *path:新的工作目录。
    返回值

  • 成功返回 0

  • 失败返回 -1errno 会被设置。
    示例代码

if (chdir("/home/user/documents") != 0) {
    perror("chdir failed");
    return -1;
}

解释

  • chdir("/home/user/documents"):将当前工作目录更改为 /home/user/documents

  • 如果失败,返回值为 -1,程序通过 perror 输出错误信息。

2.5 getcwd() 函数

功能:获取当前工作目录。
参数

  • char *buf:存储路径的缓冲区。

  • size_t size:缓冲区大小。
    返回值

  • 成功返回路径字符串。

  • 失败返回 NULL
    示例代码

char cwd[1024];
if (getcwd(cwd, sizeof(cwd)) == NULL) {
    perror("getcwd failed");
    return -1;
}
printf("Current working directory: %s\n", cwd);

解释

  • getcwd(cwd, sizeof(cwd)):获取当前工作目录,并存储在缓冲区 cwd 中。

  • 如果失败,返回值为 NULL,程序通过 perror 输出错误信息。

2.6 mkdir() 函数

功能:创建目录。
参数

  • const char *pathname:目录名。

  • mode_t mode:权限模式。
    返回值

  • 成功返回 0

  • 失败返回 -1errno 会被设置。
    示例代码

if (mkdir("new_directory", 0755) != 0) {
    perror("mkdir failed");
    return -1;
}

解释

  • mkdir("new_directory", 0755):以权限 0755 创建名为 "new_directory" 的目录。

  • 如果失败,返回值为 -1,程序通过 perror 输出错误信息。

2.7 rmdir() 函数

功能:删除空目录。
参数

  • const char *pathname:目录名。
    返回值

  • 成功返回 0

  • 失败返回 -1errno 会被设置。
    示例代码

if (rmdir("empty_directory") != 0) {
    perror("rmdir failed");
    return -1;
}

解释

  • rmdir("empty_directory"):删除名为 "empty_directory" 的空目录。

  • 如果失败,返回值为 -1,程序通过 perror 输出错误信息。

以下是将使用 freadfwritefgetcfputcfgetsfputsreadwrite 函数实现 cpcat 操作的代码整合到博客中的内容:

使用 freadfwrite 实现 cpcat

#include 

void do_copy(FILE *src, FILE *dest) {
    char buffer[1024];
    size_t bytes_read;

    while ((bytes_read = fread(buffer, 1, sizeof(buffer), src)) > 0) {
        fwrite(buffer, 1, bytes_read, dest);
    }
}

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s  \n", argv[0]);
        return 1;
    }

    FILE *src = fopen(argv[1], "rb");
    if (!src) {
        perror("Failed to open source file");
        return 1;
    }

    FILE *dest = fopen(argv[2], "wb");
    if (!dest) {
        perror("Failed to open destination file");
        fclose(src);
        return 1;
    }

    do_copy(src, dest);

    fclose(src);
    fclose(dest);

    return 0;
}
#include 

int main(int argc, char *argv[]) {
    if (argc < 3) {
        fprintf(stderr, "Usage: %s   [resume_offset]\n", argv[0]);
        return 1;
    }

    FILE *src = fopen(argv[1], "rb");
    if (!src) {
        perror("Failed to open source file");
        return 1;
    }

    FILE *dest = fopen(argv[2], "r+b");
    if (!dest) {
        dest = fopen(argv[2], "w+b");
        if (!dest) {
            perror("Failed to open destination file");
            fclose(src);
            return 1;
        }
    }

    if (argc >= 4) {
        long offset = strtol(argv[3], NULL, 10);
        fseek(dest, offset, SEEK_SET);
    }

    char buffer[1024];
    size_t bytes_read;

    while ((bytes_read = fread(buffer, 1, sizeof(buffer), src)) > 0) {
        fwrite(buffer, 1, bytes_read, dest);
    }

    fclose(src);
    fclose(dest);

    return 0;
}

使用 fgetcfputc 实现 cpcat

#include 

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s  \n", argv[0]);
        return 1;
    }

    FILE *src = fopen(argv[1], "r");
    if (!src) {
        perror("Failed to open source file");
        return 1;
    }

    FILE *dest = fopen(argv[2], "w");
    if (!dest) {
        perror("Failed to open destination file");
        fclose(src);
        return 1;
    }

    int c;
    while ((c = fgetc(src)) != EOF) {
        fputc(c, dest);
    }

    fclose(src);
    fclose(dest);

    return 0;
}

使用 fgetsfputs 实现 cpcat

#include 

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s  \n", argv[0]);
        return 1;
    }

    FILE *src = fopen(argv[1], "r");
    if (!src) {
        perror("Failed to open source file");
        return 1;
    }

    FILE *dest = fopen(argv[2], "w");
    if (!dest) {
        perror("Failed to open destination file");
        fclose(src);
        return 1;
    }

    char buffer[1024];
    while (fgets(buffer, sizeof(buffer), src)) {
        fputs(buffer, dest);
    }

    fclose(src);
    fclose(dest);

    return 0;
}

使用 readwrite 实现 cpcat

#include 
#include 
#include 

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s  \n", argv[0]);
        return 1;
    }

    int src_fd = open(argv[1], O_RDONLY);
    if (src_fd == -1) {
        perror("Failed to open source file");
        return 1;
    }

    int dest_fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if (dest_fd == -1) {
        perror("Failed to open destination file");
        close(src_fd);
        return 1;
    }

    char buffer[1024];
    ssize_t bytes_read;

    while ((bytes_read = read(src_fd, buffer, sizeof(buffer))) > 0) {
        write(dest_fd, buffer, bytes_read);
    }

    close(src_fd);
    close(dest_fd);

    return 0;
}
#include 
#include 
#include 
#include 

int main(int argc, char *argv[]) {
    if (argc < 3) {
        fprintf(stderr, "Usage: %s   [resume_offset]\n", argv[0]);
        return 1;
    }

    int src_fd = open(argv[1], O_RDONLY);
    if (src_fd == -1) {
        perror("Failed to open source file");
        return 1;
    }

    int dest_fd = open(argv[2], O_WRONLY | O_CREAT, 0666);
    if (dest_fd == -1) {
        perror("Failed to open destination file");
        close(src_fd);
        return 1;
    }

    off_t offset = 0;
    if (argc >= 4) {
        offset = strtol(argv[3], NULL, 10);
        if (lseek(dest_fd, offset, SEEK_SET) == -1) {
            perror("Failed to seek destination file");
            close(src_fd);
            close(dest_fd);
            return 1;
        }
    }

    char buffer[1024];
    ssize_t bytes_read;

    while ((bytes_read = read(src_fd, buffer, sizeof(buffer))) > 0) {
        if (write(dest_fd, buffer, bytes_read) != bytes_read) {
            perror("Failed to write to destination file");
            close(src_fd);
            close(dest_fd);
            return 1;
        }
    }

    close(src_fd);
    close(dest_fd);

    return 0;
}

以上代码分别使用了不同的文件操作函数实现 cpcat 操作,每种方法都有其适用场景和特点。你可以根据具体需求选择合适的函数组合。

你可能感兴趣的:(c语言,linux,算法)