我有大型(数百 MB 或更多)文件,我需要在 Windows 上使用 C++ 读取 block 。目前相关功能有:
errorType LargeFile::read( void* data_out, __int64 start_position, __int64 size_bytes ) const
{
if( !m_open ) {
// return error
}
else {
seekPosition( start_position );
DWORD bytes_read;
BOOL result = ReadFile( m_file, data_out, DWORD( size_bytes ), &bytes_read, NULL );
if( size_bytes != bytes_read || result != TRUE ) {
// return error
}
}
// return no error
}
void LargeFile::seekPosition( __int64 position ) const
{
LARGE_INTEGER target;
target.QuadPart = LONGLONG( position );
SetFilePointerEx( m_file, target, NULL, FILE_BEGIN );
}
上面的表现好像不是很好。读取文件的 4K block 。有些读数是连贯的,但大多数不是。
有几个问题:是否有一种分析读数的好方法?哪些东西可以提高性能?例如,对数据进行行业调整会有用吗?我对文件 I/O 优化还比较陌生,所以文章/教程的建议或指针会很有帮助。
最佳答案
这里的“连贯”是什么意思一点都不清楚。
在任何情况下,您都可以从考虑如何真正使用文件中的数据开始。如果您主要从头到尾阅读连续 block 中的文件,您可能会受益于在调用 CreateFile
时传递 FILE_FLAG_SEQUENTIAL_SCAN
。相反,如果您主要使用一个地方的一个 block ,然后很可能不使用与其(几乎)连续的另一个 block ,您可能会受益于传递 FILE_FLAG_RANDOM_ACCESS
。如果您有理由确定在读取一个数据 block 后,您将不会很快再次使用同一个数据 block ,您可能会受益于使用 FILE_FLAG_NO_BUFFERING
.
另一种可能性是一次读取更大的数据 block ,前提是您可以利用额外的数据。一次只读取 4K 往往会带来相当大的开销。
最后,如果您可以断开处理与读取本身的连接,您可能需要考虑使用异步读取。基本思想是你可以告诉它读取一些数据,当数据被读取后你可以处理数据 block ——但在这两者之间,你可以做其他事情——比如发出更多的读取,所以磁盘会几乎总是忙于读取数据。
关于c++ - 提高文件读取性能(单个文件、C++、Windows),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2724225/