读取文件的速度比boost :: file_mapping更快?

时间:2012-12-16 21:48:19

标签: c++ windows file memory io

我正在编写一个对延迟敏感的应用程序,该应用程序在初始化时读取文本文件。我已经对我的所有算法进行了分析和重写,因此85%的执行时间来自以下几行:

boost::interprocess::file_mapping file(Path, read_only);
boost::interprocess::mapped_region data(file, read_only);

我在windows上写这个 - 有没有更快的方法将文件映射到内存?便携性不是一个问题。

3 个答案:

答案 0 :(得分:3)

你可以使用Win32的原生函数,但我认为你不会节省很多,因为boost不会增加很多开销:

OFSTRUCT ofStruct;
ofStruct.cBytes=sizeof (OFSTRUCT);
HANDLE file=(HANDLE)OpenFile(fileName, &ofStruct, OF_READ); 
if (file==INVALID_HANDLE_VALUE) 
  handle errors
else {
  HANDLE map=CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, 0);
  if (map==INVALID_HANDLE_VALUE) 
    handle errors
  else {
    const char *p=(const char *)MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0));
    if (p) {
      // enjoy using p to read access file contents.
    }
    // close all that handles now...
  }

答案 1 :(得分:1)

我建议放弃文件映射的想法。

FM是一个复杂的结构,增加了一些开销。纯文本缓存读取还涉及与物理设备的非平凡交互。你可以做无缓冲的读取。可能接下来要问的是你真正想要什么样的IO - 文件有多大?它顺序吗?它在网络上吗?您可以选择硬件,还是在客户的机器上?

答案 2 :(得分:1)

如果文件很小,只需打开并使用标准的Win32 CreateFile()/ ReadFile()API将它们读入内存。

如果您按顺序使用每个文件(或者可以按照这样的方式安排代码),则应指定FILE_FLAG_SEQUENTIAL_SCAN。这是文件/缓存子系统积极预读的提示。对于小文件,在第一次调用ReadFile()之前,可能会将文件读入缓存。

编辑:根据要求,这是一个片段,说明使用Win32 API将文件内容读入字节向量:

void ReadFileIntoBuffer( const std::wstring& fileName, std::vector< uint8_t >& output )
{
    HANDLE hFile( INVALID_HANDLE_VALUE );
    try 
    {
        // Open the file.
        hFile = CreateFile( filename.c_str(), 
                                 GENERIC_READ,
                                 FILE_SHARE_READ,
                                 NULL,
                                 OPEN_EXISTING, 
                                 FILE_FLAG_SEQUENTIAL_SCAN,
                                 NULL );
        if( INVALID_HANDLE_VALUE != hFile )
            throw std::runtime_error( "Failed to open file." );

        // Fetch size
        LARGE_INTEGER fileSize;
        if( !GetFileSizeEx( hFile, &fileSize ) );
            throw std::runtime_error( "GetFileSizeEx() failed." );

        // Resize output buffer.
        output.resize( fileSize.LowPart );

        // Read the file contents.
        ULONG bytesRead;
        if( !ReadFile( hFile, &output[0], fileSize.LowPart, &bytesRead, NULL ) )
            throw std::runtime_error( "ReadFile() failed." );

        // Recover resources.
        CloseHandle( hFile );
    }
    catch( std::exception& ) 
    {
        // Dump the error.
        std::cout << e.what() << " GetLastError() = " << GetLastError() << std::endl;

        // Recover resources.
        if( INVALID_HANDLE_VALUE != hFile )
            CloseHandle( hFile );

        throw;
    }
}