我正在编写一个对延迟敏感的应用程序,该应用程序在初始化时读取文本文件。我已经对我的所有算法进行了分析和重写,因此85%的执行时间来自以下几行:
boost::interprocess::file_mapping file(Path, read_only);
boost::interprocess::mapped_region data(file, read_only);
我在windows上写这个 - 有没有更快的方法将文件映射到内存?便携性不是一个问题。
答案 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;
}
}