C++访问磁盘卷(如U盘)修改字节恢复已删除文件问题咨询
磁盘卷原始字节读写与删除文件恢复实现方案
你尝试使用fstream binaryFile("E:", ios::in | ios::out | ios::binary);直接访问卷的方案不可行,C++标准库的fstream默认仅支持操作文件系统层级的普通文件,无法直接访问磁盘块设备,必须结合操作系统原生API实现需求。
Windows平台实现方案
前置要求
- 程序必须以管理员身份运行,否则操作系统会拒绝卷访问请求
- 读写操作的偏移量、读写长度必须是磁盘扇区大小的整数倍(通常为512字节或4KB)
- 操作目标卷前建议先对卷加锁,避免系统后台写入导致数据不一致
核心实现代码
使用Windows原生CreateFileAPI打开卷,设备路径格式为\\.\盘符:,C++字符串中需要转义为\\\\.\\盘符:
#include <windows.h> #include <iostream> int main() { // 打开E盘卷 HANDLE hVolume = CreateFileA("\\\\.\\E:", GENERIC_READ | GENERIC_WRITE, // 读写权限 FILE_SHARE_READ | FILE_SHARE_WRITE, // 共享模式 NULL, OPEN_EXISTING, // 卷是已存在的设备,固定用此参数 FILE_ATTRIBUTE_NORMAL, NULL); if (hVolume == INVALID_HANDLE_VALUE) { std::cout << "打开卷失败,错误码:" << GetLastError() << std::endl; return 1; } // 获取当前卷的扇区大小 DWORD bytesPerSector; GetDiskFreeSpaceA("E:\\", NULL, &bytesPerSector, NULL, NULL); // 示例:读取卷第一个扇区内容 char* sectorBuffer = new char[bytesPerSector]; DWORD readCount; ReadFile(hVolume, sectorBuffer, bytesPerSector, &readCount, NULL); // 此处可解析扇区内容,判断文件系统类型(FAT32/NTFS/exFAT等) // 示例:写入指定偏移位置,偏移必须为扇区大小整数倍 LARGE_INTEGER writeOffset; writeOffset.QuadPart = bytesPerSector * 2; // 写入第3个扇区位置 SetFilePointerEx(hVolume, writeOffset, NULL, FILE_BEGIN); WriteFile(hVolume, sectorBuffer, bytesPerSector, &readCount, NULL); // 释放资源 CloseHandle(hVolume); delete[] sectorBuffer; return 0; }
Linux平台实现方案
Linux下块设备以文件形式存在于/dev目录下,例如U盘第一个分区通常为/dev/sdb1,无需特殊API:
- 需要以root权限运行程序
- 可以直接用标准fstream打开
/dev/sdb1路径,也可以用open系统调用操作,同样要注意扇区对齐
删除文件恢复的核心逻辑
- 读取卷的引导扇区,解析对应文件系统的结构参数
- 遍历文件系统的索引结构:FAT32遍历文件分配表,NTFS遍历主文件表(MFT)
- 找到标记为已删除的文件条目:多数文件系统删除文件仅会修改文件头的删除标记,对应存储数据的簇/扇区位置不会立刻被清空
- 确认目标文件对应的扇区未被新写入的数据覆盖,直接读取对应扇区的内容导出为新文件即可
注意:操作前建议先对目标卷做完整镜像备份,直接操作原磁盘如果出现误写可能导致原有数据永久损坏,也不要在要恢复数据的磁盘上写入任何新内容,避免覆盖已删除文件的残留数据。
内容的提问来源于stack exchange,提问作者Duc Thang
相关产品推荐
相关产品推荐

