我正在编写一个程序来检查文件是否是PE文件。为此,我只需要读取文件的文件头(我想这不会超过文件的前1024个字节)。
我尝试使用creatfile()+ readfile()组合,结果会变慢,因为我正在遍历系统驱动器中的所有文件。只需要15-20分钟来迭代它们。
您能告诉我们打开和阅读文件的其他方法,以加快速度吗?
注意:请注意我不需要完整阅读该文件。我只需要读取文件的初始部分 - DOS标头,PE标头等,我猜这个文件的前512字节不会超过。
这是我的代码:
bool IsPEFile(const String filePath)
{
HANDLE hFile = CreateFile(filePath.c_str(),
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
DWORD dwBytesRead = 0;
const DWORD CHUNK_SIZE = 2048;
BYTE szBuffer[CHUNK_SIZE] = {0};
LONGLONG size;
LARGE_INTEGER li = {0};
if (hFile != INVALID_HANDLE_VALUE)
{
if(GetFileSizeEx(hFile, &li) && li.QuadPart > 0)
{
size = li.QuadPart;
ReadFile(hFile, szBuffer, CHUNK_SIZE, &dwBytesRead, NULL);
if(dwBytesRead > 0 && (WORDPTR(szBuffer[0]) == ('M' << 8) + 'Z' || WORDPTR(szBuffer[0]) == ('Z' << 8) + 'M'))
{
LONGLONG ne_pe_header = DWORDPTR(szBuffer[0x3c]);
WORD signature = 0;
if(ne_pe_header <= dwBytesRead-2)
{
signature = WORDPTR(szBuffer[ne_pe_header]);
}
else if (ne_pe_header < size )
{
SetFilePointer(hFile, ne_pe_header, NULL, FILE_BEGIN);
ReadFile(hFile, &signature, sizeof(signature), &dwBytesRead, NULL);
if (dwBytesRead != sizeof(signature))
{
return false;
}
}
if(signature == 0x4550) // PE file
{
return true;
}
}
}
CloseHandle(hFile);
}
return false;
}
提前致谢。
答案 0 :(得分:2)
我认为您正在克服机械硬盘驱动器的固有局限性。您没有提及您是使用硬盘还是固态硬盘,但我认为您的文件访问速度很慢,我认为是硬盘。
HDD可以按顺序以大约100 MB / s的速度读取数据,但寻道时间有点超过10 ms。这意味着如果您寻找某个位置(10毫秒),您也可以读取一兆字节的数据(另一个10毫秒)。这也意味着您每秒只能访问少于100个文件。
因此,在您的情况下,您是否正在读取文件的前512个字节或文件的前100字节并不重要。
硬件便宜,程序员时间昂贵。如果文件访问速度太慢,最好的办法是购买固态磁盘驱动器。我预测最终所有计算机都将拥有固态磁盘驱动器。
注意:如果瓶颈是硬盘驱动器,除了用更好的技术更换硬盘驱动器之外,你无能为力。实际上所有文件访问机制都同样慢。你唯一能做的就是只读取文件的初始部分,如果文件非常大,例如多兆字节。但根据您的代码示例,您已经这样做了。
答案 1 :(得分:-1)
要获得更快的文件IO,您需要使用Win32的CreateFile
和ReadFile
API。
如果您想加快速度,可以使用文件缓冲并使用重叠的IO或IOCP使文件无阻塞。
请参阅此示例以获取帮助:https://msdn.microsoft.com/en-us/library/windows/desktop/bb540534%28v=vs.85%29.aspx
我认为C和C ++的FILE
和fstream
分别不比Win32快。