我正在尝试使用ReadFile函数。这是我的代码:
#define BUFFERSIZE 5
int main(int argc, char* argv[])
{
OVERLAPPED overlapIn = {};
HANDLE tHandle;
char buf[BUFFERSIZE] = {};
DWORD lpNumberOfBytesRead;
tHandle = CreateFile(
L"\\\\.\\D:",
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (tHandle == INVALID_HANDLE_VALUE)
{
DWORD error = GetLastError();
assert(0);
}
if (ReadFile(tHandle, &buf, BUFFERSIZE - 1, &lpNumberOfBytesRead, NULL) == 0)
{
int error = GetLastError();
printf("Terminal failure: Unable to read from disk.\n GetLastError=%d\n", error);
CloseHandle(tHandle);
return 1;
}
GetLastError函数返回代码87,即ERROR_INVALID_PARAMETER。
很明显,其中一个参数是错误的,但我不知道哪一个,因为我试图做一切像文档中所写的一样。
答案 0 :(得分:3)
即使未在CreateFile中指定非高速缓存选项,也可以根据特定文件系统的判断将卷句柄打开为非高速缓存。您应该假设所有Microsoft文件系统都将未处理的卷句柄打开。
MSDN article on File Buffering描述了非缓存句柄的要求:
文件访问大小(包括OVERLAPPED结构中的可选文件偏移量,如果指定)必须是多个字节,它是卷扇区大小的整数倍。例如,如果扇区大小为512字节,则应用程序可以请求读取和写入512,1024,1,536或2,048字节,但不能请求335,981或7,171字节。
用于读取和写入操作的文件访问缓冲区地址应该是物理扇区对齐的,这意味着在内存中的地址上对齐,该地址是卷的物理扇区大小的整数倍。根据磁盘的不同,可能不会强制执行此要求。
严格的代码应检查相关文件系统的扇区大小,然后使用this approach分配内存。但是,根据我的经验,扇区大小始终小于或等于分配粒度,因此您可以使用VirtualAlloc()来分配内存块。
答案 1 :(得分:0)
缓冲区大小需要与hdd sectorize对齐
WIN32_FIND_DATA atr = {0};
DWORD BYTES_PER_SECTOR;
char path[MAX_PATH];
/* get path length current dir */
const size_t len = GetCurrentDirectory(0, 0);
/* set path to path char array */
GetCurrentDirectory(len, path);
/* windows function to get disk details */
GetDiskFreeSpace(NULL, NULL, &BYTES_PER_SECTOR, NULL, NULL);
/* find first file in dir */
find = FindFirstFile(path, &atr);
for(;find != INVALID_HANDLE_VALUE;){
/* get the file size */
DWORD filesize = atr.nFileSizeLow;
if(atr.nFileSizeHigh > 0){
filesize = atr.nFileSizeHigh;
filesize = (filesize << 31);
filesize = atr.nFileSizeLow;
}
/* sector size aligned file size */
size_t buffer_size = ((BYTES_PER_SECTOR + ((filesize + BYTES_PER_SECTOR)-1)) & ~(BYTES_PER_SECTOR -1));
/* create buffer */
DWORD buffer[buffer_size];
/* create a new file or open an existing file */
handle = CreateFile(&path[0], GENERIC_READ | GENERIC_WRITE, 0 , NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL))!=INVALID_HANDLE_VALUE)
/* read the file in to buffer */
ReadFile(handle, (void*)&buffer, buffer_size, &bytesread, NULL)
if(FindNextFile(find, &atr)==0){ printf("last file processed, leaving\n");break;};
}
CloseHandle(file);
FindClose(find);