从集群读取数据

Reading data off of a cluster

本文关键字:数据 读取      更新时间:2023-10-16

我需要帮助从使用CreateFile()的文件的最后一个集群读取数据,然后使用ReadFile()。首先,我被我的ReadFile()的零结果困住了,因为我认为我在CreateFile()中设置了不正确的权限。

/**********CreateFile for volume ********/
        HANDLE hDevice = INVALID_HANDLE_VALUE;            
            hDevice = CreateFile(L"\\.\C:",    
            0,                
            FILE_SHARE_READ | 
            FILE_SHARE_WRITE,
            NULL,             
            OPEN_EXISTING,    
            0,                
            NULL);            
        if (hDevice == INVALID_HANDLE_VALUE)    
        {
            wcout << "error at hDevice at CreateFile "<< endl;
            system("pause");
        }
        /******* Read file from the volume *********/
        DWORD nRead;
        TCHAR buff[4096];
        if (BOOL fileFromVol = ReadFile(
            hDevice,
            buff,
            4096,
            &nRead,
            NULL
            ) == 0) {
            cout << "Error with fileFromVol" << "nn";
            system("pause");
        }

接下来,我有了我需要的所有集群信息和文件信息(文件大小、文件的最后一个集群位置、磁盘上的集群数量、集群大小等)。如何将卷上的指针设置为从指定的集群位置开始,以便从中读取/写入数据?

主要问题是您为dwDesiredAccess指定了0。为了读取数据,你应该指定FILE_READ_DATA .

最重要的是,我严重质疑TCHAR的使用。当您需要支持Windows 9x时,这适用于文本。最重要的是不需要支持Windows 9x,数据不是文本。缓冲区的类型应该是unsigned char

显然,你需要的缓冲区是集群大小的倍数。您已经硬编码了4096,但是真正的代码应该查询集群大小。

当这两个API调用中的任何一个失败时,它们在最后一个错误值中指出失败原因。可以通过调用GetLastError获取。当ReadFile失败时,它将返回ERROR_ACCESS_DENIED

您可以通过调用SetFilePointerEx在卷中查找。同样,您需要查找集群大小的多个倍数。

LARGE_INTEGER dist;
dist.QuadPart = ClusterNum * ClusterSize;
BOOL res = SetFilePointerEx(hFile, dist, nullptr, FILE_BEGIN);
if (!res)
    // handle error

如果是顺序读取,则不需要设置文件指针。对ReadFile的调用将自动推进。

在进行随机访问I/O时,完全不要打乱存储在文件句柄中的文件指针。相反,使用OVERLAPPED结构并为每个I/O操作指定位置。

这甚至适用于同步I/O(如果文件打开时没有FILE_FLAG_OVERLAPPED)。

当然,正如David所提到的,如果您在没有足够访问权限的情况下使用打开的文件句柄执行操作,您将获得ERROR_ACCESS_DENIED