首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >要取消删除文件的C#类?

要取消删除文件的C#类?
EN

Stack Overflow用户
提问于 2012-01-11 12:25:17
回答 1查看 18.5K关注 0票数 14

可能重复:

How do I restore a file from the recycle bin using C#?

Recovering deleted file on windows

我正在开发一个应用程序,该应用程序旨在从系统中恢复已删除的文件(那些来自回收站的文件和那些已经从回收站清空但仍然可以理解的文件)和格式化驱动器。我决定把c#作为语言,但是我很难找到处理这个问题的类。是否有人知道任何类/方法用于查找已删除的文件、检索它们或在此问题上提供任何教程或帮助。我在这个问题上没有什么经验,所以如果能提供任何帮助,我们将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-01-11 13:34:25

没有内置的类来执行您要求的

实际上,删除文件是一个困难的过程,它需要非常低层次的文件系统知识。因此,首先要做的是获取有关包含要取消删除的文件的驱动器的信息。基本上,你首先想知道它的文件系统。

您将不得不大量使用P/Invoke。首先要掌握你的目标驱动器的手柄:

代码语言:javascript
复制
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CloseHandle(IntPtr handle);

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr CreateFile(
    string lpFileName,
    uint dwDesiredAccess,
    uint dwShareMode,
    IntPtr lpSecurityAttributes,
    uint dwCreationDisposition,
    int dwFlagsAndAttributes,
    IntPtr hTemplateFile);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool GetVolumeInformationByHandleW(
    IntPtr hDisk,
    StringBuilder volumeNameBuffer,
    int volumeNameSize,
    ref uint volumeSerialNumber,
    ref uint maximumComponentLength,
    ref uint fileSystemFlags,
    StringBuilder fileSystemNameBuffer,
    int nFileSystemNameSize);

// Gets a handle to the drive
// Note: use CloseHandle to close the handle you opened once work is done
IntPtr hDrive = NativeMethods.CreateFile(
    string.Format("\\\\.\\{0}:", DriveLetter)
    GenericRead,
    Read | Write,
    IntPtr.Zero,
    OpenExisting,
    0,
    IntPtr.Zero);

// Then gets some information about the drive
// The following function requires Vista+
// Use GetVolumeInformation for older systems
const int VolumeNameSize = 255;
const int FileSystemNameBufferSize = 255;
StringBuilder volumeNameBuffer = new StringBuilder(VolumeNameSize);
uint volumeSerialNumber = 0;
uint maximumComponentLength = 0;
uint fileSystemFeatures;
StringBuilder fileSystemNameBuffer = new StringBuilder(FileSystemNameBufferSize);

GetVolumeInformationByHandleW(
    hDrive,
    volumeNameBuffer,
    VolumeNameSize,
    ref volumeSerialNumber,
    ref maximumComponentLength,
    ref fileSystemFeatures,
    fileSystemNameBuffer,
    FileSystemNameBufferSize);

// Now you know the file system of your drive
// NTFS or FAT16 or UDF for instance
string FileSystemName = fileSystemNameBuffer.ToString();

一旦您有了文件系统的名称,就必须手动从驱动器读取原始数据。将完全取决于驱动器的文件系统。无论如何,您必须获得相关硬盘的句柄:

代码语言:javascript
复制
// Gets a handle to the physical disk
IntPtr hDisk = CreateFile(string.Format("\\\\.\\PhysicalDrive{0}", diskNumber),
    GenericRead,
    Read | Write,
    0,
    OpenExisting,
    0,
    IntPtr.Zero);

现在你必须对你的文件系统有很多了解.对于NTFS文件系统,您必须了解Master File Table的概念。实际上,这很难。对于FAT文件系统,这并不复杂,但仍然需要学习一段时间的FS。从wikipedia开始。

从使用CreateFile获得的句柄中,您现在将读取(每个扇区)每个字节的(原始访问)字节到磁盘中,以便使用ReadFile获取您想要的信息。

代码语言:javascript
复制
// Used to read in a file
[DllImport("kernel32.dll")]
public static extern bool ReadFile(
    IntPtr hFile,
    byte[] lpBuffer,
    uint nNumberOfBytesToRead,
    ref uint lpNumberOfBytesRead,
    IntPtr lpOverlapped);

// Used to set the offset in file to start reading
[DllImport("kernel32.dll")]
public static extern bool SetFilePointerEx(
    IntPtr hFile,
    long liDistanceToMove,
    ref long lpNewFilePointer,
    uint dwMoveMethod);

// Set offset
int bufferSize = 512;
byte[] buffer = new byte[bufferSize];
SetFilePointerEx(
    hDisk,
    offset,
    ref pt,
    FileBegin);

// Read a whole sector
// Note that you can't read less than a whole sector of your physical disk. Usually it's 512 bytes,
// but you'll have to retrieve this information from the disk geometry. If you're interested, I can provide you
// some code. It requires the use of the IOCTL_DISK_GET_DRIVE_GEOMETRY control code.
uint read = 0;
ReadFile(
    hDisk,
    buffer,
    bufferSize,
    ref read,
    IntPtr.Zero);

对于NTFS来说,首先要获得MFT的起始扇区.然后你必须“解析”MFT并查找已删除的文件..。

我不会在这里解释整个过程。有关示例,请参见this link

所以祝你好运:)

现在,您可能希望使用一个第三方应用程序,该应用程序已经完成了所有这些工作,并从您自己的程序(如注释中所说的命令行工具)中使用它。

票数 49
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8819188

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档