用Windows的文件映射机制,实现大批量数据的快速存储(4)
mWriteBuffer = MapViewOfFile(mMappingHandle, FILE_MAP_WRITE, (DWORD)(mWriteMappingOffset>>32), (DWORD)(mWriteMappingOffset & 0xFFFFFFFF), mMappingViewSize);
mWriteBufferOffset = 0;
datacanwrite = mMappingViewSize - mWriteBufferOffset;
if (! mWriteBuffer) {
DumpWindowsErrorMessage();
enstLogService *logservice = enstLogService::GetMyAddr();
logservice->AppendLog(this, "Error when map view of file.");
return false;
}
}
int datatowrite = pDataLength - datawrote;
int actualdatatowrite = (datacanwrite >= datatowrite)?datatowrite:datacanwrite;
memcpy((PBYTE)mWriteBuffer+mWriteBufferOffset, (PBYTE)pData+datawrote, actualdatatowrite);
mWriteBufferOffset += actualdatatowrite;
datawrote += actualdatatowrite;
} while (datawrote < pDataLength);
return true;
}
bool enstFileCache::ReadData(T_INT64 pAddressOffset, T_INT8* pData, int pDataLength)
{
int datareaded = 0;
do {
int datacanread = mReadMappingOffset + mMappingViewSize - pAddressOffset - datareaded;
if (mReadBuffer && (datacanread <= 0 || datacanread > mMappingViewSize)) {
UnmapViewOfFile(mReadBuffer);
mReadBuffer = NULL;
}
if (mReadBuffer == NULL) {
mReadMappingOffset = (pAddressOffset + datareaded) / mMappingViewSize * mMappingViewSize;
mReadBuffer = MapViewOfFile(mMappingHandle, FILE_MAP_READ, (DWORD)(mReadMappingOffset>>32), (DWORD)(mReadMappingOffset & 0xFFFFFFFF), mMappingViewSize);
datacanread = mReadMappingOffset + mMappingViewSize - pAddressOffset - datareaded;
if (! mReadBuffer) {
DumpWindowsErrorMessage();
enstLogService *logservice = enstLogService::GetMyAddr();
logservice->AppendLog(this, "Error when map view of file.");
return false;
}
}
int datatoread = pDataLength - datareaded;
int actualdatatoread = (datacanread >= datatoread)?datatoread:datacanread;
memcpy((PBYTE)pData+datareaded, (PBYTE)mReadBuffer+pAddressOffset-mReadMappingOffset+datareaded, actualdatatoread);
datareaded += actualdatatoread;
} while (datareaded < pDataLength);
return true;
}
void enstFileCache::DumpWindowsErrorMessage()
{
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
enstLogService *logservice = enstLogService::GetMyAddr();
logservice->AppendLog(this, (LPTSTR)lpMsgBuf);
//puts((LPTSTR)lpMsgBuf);
LocalFree(lpMsgBuf);
}
#ifdef WIN32
#include "moc_enstfilecache.cpp"
#endif
由于系统是用QT开发的,因此类中使用了不少QT的类,同时也使用了系统中的部分工具类,不过基本工作原理相信你是能够看懂的。另外,整个系统是计划要跨平台使用的,因此今后还需要实现Linux下的类似功能,目前这个版本被绑定在Windows平台上了,不幸。
- 上一篇:vc中如何使用设备描述表
- 下一篇:Visual C#程序员面试基础问题和答案