gpt4 book ai didi

c++ - 在 C++ 中读取磁盘中文件的最快方法是什么?

转载 作者:行者123 更新时间:2023-11-30 21:25:30 24 4
gpt4 key购买 nike

我正在编写一个程序来检查文件是否是PE文件。为此,我只需要读取文件的文件头(我猜它占用的空间不会超过文件的前 1024 个字节)。

我尝试使用 creatfile() + readfile() 组合,结果发现速度较慢,因为我正在迭代系统驱动器中的所有文件。仅迭代它们就需要 15-20 分钟。

您能否告诉我们一些打开和读取文件以使其更快的替代方法?

注意:请注意我不需要阅读整个文件。我只需要读取文件的初始部分——DOS header 、PE header 等,我猜它们不会占用超过文件的前 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;
}

提前致谢。

最佳答案

我认为您遇到了机械硬盘驱动器的固有局限性。您没有提到您使用的是 HDD 还是固态硬盘,但考虑到您的文件访问速度很慢,我假设是 HDD。

HDD 可以以大约 100 MB/s 的速度连续读取数据,但寻道时间略高于 10 毫秒。这意味着,如果您寻找某个位置(10 毫秒),您可能还需要读取一兆字节的数据(另外 10 毫秒)。这也意味着您每秒只能访问不到 100 个文件。

因此,就您的情况而言,读取文件的前 512 字节还是文件的前 100 KB 并不重要。

硬件很便宜,程序员的时间很昂贵。如果您的文件访问速度太慢,最好的选择是购买固态磁盘驱动器。我预测最终所有计算机都将拥有固态磁盘驱动器。

注意:如果瓶颈是硬盘,除了更换技术更好的硬盘外,没有什么办法。实际上所有文件访问机制都同样慢。如果文件非常大(例如多个兆字节),您唯一可以做的就是仅读取文件的初始部分。但根据您的代码示例,您已经这样做了。

关于c++ - 在 C++ 中读取磁盘中文件的最快方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29270393/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com