C语言实现文件备份:标准库与系统调用双法详解

陆遥
陆遥
发布时间:2026-10-15 | 4人浏览过
原创

本文将介绍利用 C/C++ 语言进行文件备份的两种主流方案:使用标准 I/O 库函数以及 Linux 系统调用。通过提供完整可运行的源代码、执行步骤解析及关键 API 的参数说明,帮助用户在编程实验或工程实践中高效实现文件的复制与归档。

一、使用标准 I/O 库实现文件备份

在常规的应用程序开发中,使用标准 C 库是最为便捷的方式。标准库提供了高级的文件指针接口 fopen()、fread() 等,自动处理了缓冲区和底层的打开/关闭逻辑,极大地简化了代码编写。

第1步:编写标准库版本代码

该方案采用双指针对照机制,一个指向源文件只读,另一个指向目标文件只写。中间使用 buffer 作为临时存储区,循环执行读取和写入动作。

#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using namespace std;
signed main(void){
    ios; // 加速 C++ IO 流
  
    FILE *fp, *fq; // 定义文件流指针
  
    // 1. 打开源文件用于读取
    if((fp = fopen("source", "r"))) {
        cout << "success in readfile open!" << endl;
    } else {
        cout << "can't open readfile!" << endl;
        exit(1);
    }
  
    // 2. 创建并打开目标文件用于写入(覆盖原有内容)
    if((fq = fopen("target", "w"))) {
        cout << "success in writefile open!" << endl;
    } else {
        cout << "can't open writefile!" << endl;
        exit(1);
    }
  
    char buffer[20]; // 定义固定大小的字符缓冲区
  
    // 3. 循环读取数据块
    while(fread(buffer, sizeof(char), 20, fp)) {
        fwrite(buffer, sizeof(char), 20, fq); // 同步写入目标文件
    }
  
    // 4. 安全关闭所有资源
    if(!fclose(fp)){
        cout << "success in readfile close!" << endl;
    } else {
        cout << "can't close readfile!" << endl;
        exit(1);
    }
    if(!fclose(fq)){
        cout << "success in writefile close!" << endl;
    } else {
        cout << "can't close writefile!" << endl;
        exit(1);
    }
    return 0;
}

当源文件 source 存在时,编译运行上述代码即可生成完全一致的 target 文件。控制台会输出成功打开和关闭文件流的日志信息:

第2步:IO重定向替代方案(特定场景优化)

如果仅需要在控制台下简单地重定向输入输出流,可以使用 freopen 将标准输入 stdin 绑定到源文件,将 stdout) 绑定到目标文件,利用极少的代码实现逐字节拷贝:

#include<bits/stdc++.h>
using namespace std;
signed main(void){
    freopen("source", "r", stdin);
    freopen("target", "w", stdout);
    char c;
    while((c = getchar()) != EOF) putchar(c);
    return 0;
}

注意:此方法受限于命令行环境,无法直接修改文件名而不改变程序逻辑,且效率较低,通常仅用于测试或特定脚本场景。

二、使用 Linux 系统调用实现文件备份

对于嵌入式开发或高性能网络服务,可能需要绕过标准缓冲层,直接操作内核提供的文件描述符(File Descriptor)。这需要调用 <unistd.h> 和 <fcntl.h> 等头文件中的 open()、read() 和 write() 函数。

第1步:准备带参数的可执行文件

系统调用方式通常需要接收外部传递的路径参数。因此,程序的 main 函数需要接受 argc 和 argv 参数来识别“源路径”和“目标路径”。

第2步:系统调用完整实现代码

该代码实现了严格的错误检查,包括参数数量校验、打开失败处理以及写入字节数的完整性验证。

#include <errno.h>
#include <fcntl.h>
#include  <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

signed main(int argc, char **argv) {
    int fp, fq;  // 源文件和目标文件的描述符
    char buffer[20];
    int nread;

    // 1. 检查命令行参数个数
    if (argc != 3) {
        printf("Usage: prog_name source target\n");
        exit(1);
    }

    // 2. 以只读方式打开源文件
    if ((fp = open(argv[1], O_RDONLY)) == -1) {
        perror("Open readfile Error");
        exit(1);
    }

    // 3. 创建目标文件(若不存在则创建,存在则清空)
    if ((fq = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR)) == -1) {
        perror("Open writefile Error");
        exit(1);
    }

    // 4. 循环执行底层 Read/Write
    while ((nread = read(fp, buffer, 20)) > 0) {
        // 校验实际写入的字节数是否等于预期读取数
        if ((write(fq, buffer, nread)) != nread) {
            printf("write error: incomplete write\n");
            break;
        }
    }

    // 5. 关闭描述符
    close(fp);
    close(fq);
    return 0;
}

第3步:执行与结果展示

编译后,在终端中使用以下命令执行:./a.out source target.dat。程序将在后台完成文件内容的精确复制。执行过程及状态如下所示:

三、核心 API 参考手册

理解文件操作的本质离不开对基础函数参数的掌控。以下是上述代码中涉及的关键函数解析:

1. 标准 I/O 库函数 (stdio.h)

  • FILE *fopen(const char *filename, const char *mode)
  • size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream):读取多个元素,返回实际读取的元素个数。
  • size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream):向流中写入元素集合。
  • int fclose(FILE *stream):刷新缓冲区并断开连接。

模式字符串 (mode) 说明:

字符含义
"r"只读(文件必须存在)
"w"只写(新建或覆盖)
"a"追加(不存在则新建)
"b"二进制模式(如 "rb", "wb")

2. 文件定位函数

  • int fseek(FILE *stream, long offset, int whence)
  • whence 取值:SEEK_SET(文件头)、SEEK_CUR(当前位置)、SEEK_END(文件尾)。

以上就是C/C++详解如何实现文件备份的详细内容,更多关于C语言文件操作技术的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表