文件复制、删除是操作系统文件系统最基础的操作,我们平时在资源管理器里右键复制、删除文件,底层本质上都是调用系统提供的 API 完成。本次实验基于 Windows API,使用 C 语言实现文件复制与删除功能,理解文件操作背后的调用逻辑,同时区分「API 直接调用」和手动读写缓冲区复制的差异。
环境:Windows + Dev-C++ / VS,依赖 Windows.h
一、原理简述
- 文件复制:
CopyFileA是 Windows 提供的文件复制 API。它接收源文件路径、目标路径、是否禁止覆盖标志。当第三个参数为TRUE,目标文件已存在时复制失败;为FALSE则直接覆盖原有文件。API 内部会完成读取源文件数据、写入新文件、更新文件元信息等操作。 - 文件删除:
DeleteFileA用于删除文件。注意:它只是删除文件目录项,磁盘上的数据块不会立刻清零,在没有被新数据覆盖前,文件数据有机会恢复,这也是数据恢复软件的原理。该 API 不能直接删除文件夹。
补充:如果想要手动实现复制(不调用 CopyFile),思路是
CreateFile打开源文件→ReadFile循环读缓冲区→WriteFile写入目标文件,适合理解 IO 读写流程。
二、完整代码实现
#include <stdio.h>
#include <windows.h>
/**
* @brief 复制文件
* @param src 源文件路径
* @param dst 目标文件路径
* @return 成功返回1,失败返回0
*/
int CopyMyFile(const char* src, const char* dst)
{
// TRUE:目标存在则不覆盖;FALSE:允许覆盖
BOOL ret = CopyFileA(src, dst, TRUE);
if (ret)
{
printf("✅ 文件复制成功:%s -> %s\n", src, dst);
return 1;
}
printf("❌ 文件复制失败,错误码:%d\n", GetLastError());
return 0;
}
/**
* @brief 删除文件
* @param path 待删除文件路径
* @return 成功返回1,失败返回0
*/
int DelMyFile(const char* path)
{
BOOL ret = DeleteFileA(path);
if (ret)
{
printf("✅ 文件删除成功:%s\n", path);
return 1;
}
printf("❌ 文件删除失败,错误码:%d\n", GetLastError());
return 0;
}
int main()
{
// 测试路径,可自行修改
char src[] = "test.txt";
char dst[] = "test_copy.txt";
CopyMyFile(src, dst);
DelMyFile(dst);
system("pause");
return 0;
}
三、代码说明
CopyFileA:A 代表 ANSI 版本字符串,对应char*;还有CopyFileW宽字符版本,配合wchar_t使用。GetLastError():获取 Windows 系统调用失败的错误码,方便排查问题,常见错误:- 2:找不到文件(源路径写错)
- 80:文件已存在(因为第三个参数 TRUE 禁止覆盖)
- 5:权限不足
DeleteFileA:无法删除正在被其他程序占用打开的文件,必须等文件句柄全部关闭后才能删除。- 局限:这套 API 只支持文件,不能直接复制 / 删除文件夹;文件夹操作需要使用
SHFileOperation或者递归遍历。
四、运行测试
- 在程序同目录新建
test.txt,随便写一点内容; - 编译运行程序;
- 程序先复制出
test_copy.txt,随后将这个副本删除; - 如果再次运行,因为副本已经不存在,删除会报错。
五、拓展思考
- 手动读写缓冲区实现复制:不用
CopyFile,自己ReadFile+WriteFile循环读写,适合学习文件 IO。 - 文件夹批量复制删除:需要递归遍历目录,逐个处理里面所有文件。
- 安全删除:普通删除只是取消目录项引用;如果要防止恢复,需要多次覆写磁盘块。
- 跨平台:Linux 下没有这套 WinAPI,使用
open/read/write/unlink系统调用实现。
六、总结
通过本次代码实现,我们直观看到高层文件操作的系统调用封装。操作系统屏蔽了磁盘扇区、文件分配表等底层细节,给应用程序提供简单易用的 API。文件复制本质是数据的读取 + 写入;文件删除只是解除文件名和磁盘数据块的映射,并不是立刻抹除数据。
1万+



被折叠的 条评论
为什么被折叠?



