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

标签 c++ c winapi visual-c++ readfile

我正在编写一个程序来检查文件是否是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/

相关文章:

c - 系统调用为用户分配内存

python - (Py)Windows 上的 GTK StatusIcon 通知

c++ - 服务和用户模式进程之间的共享全局事件不起作用

winapi - 学习 win32 API 值得吗?

位运算符可以有未定义的行为吗?

c++ - FLTK 在 Cygwin 中的应用 : GUI doesn't show?

c++ - 基类需要引用尚未构造的派生类成员

c++ - 如何检查 C++ 集中是否存在类对象?

c++ - 将 JPEG 解码为 char*

c - 在某些特定情况下访问数组时出现运行时错误