这个标志设了有用吗?The file is being opened with no system caching. This flag does not affect hard disk caching or memory mapped files
FILE_FLAG_WRITE_THROUGHWrite operations will not go through any intermediate cache, they will go directly to disk.If FILE_FLAG_NO_BUFFERING is not also specified, so that system caching is in effect, then the data is written to the system cache, but is flushed to disk without delay.If FILE_FLAG_NO_BUFFERING is also specified, so that system caching is not in effect, then the data is immediately flushed to disk without going through the system cache. The operating system also requests a write-through the hard disk cache to persistent media. However, not all hardware supports this write-through capability.
看到MSDN的页面里有这么一段补充: On 'CreateFile' you must specify the FILE_FLAG_OVERLAPPED flagThe file must be opened using the FILE_FLAG_OVERLAPPED flag when opened with CreateFile. Else if, the file position pointer is used instead of the overlapped structure, which means that the file will be sent only on the first call. subsequent calls would send only the end of the file.楼主试试看。 http://msdn.microsoft.com/en-us/library/ms740565(VS.85).aspx
else if(strncmp(pBuffer->pBuf+4,"0303",4)==0)//download game file
{
PFILE_PROPERTY pFile=(PFILE_PROPERTY)(pBuffer->pBuf+8);
//add 0830
char strFilePath[MAX_PATH];
strcpy(strFilePath,pFile->FilePath);
HANDLE hFileNew = CreateFile(
strFilePath, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL| FILE_FLAG_NO_BUFFERING, NULL);
if (hFileNew == INVALID_HANDLE_VALUE)
{
LOG.LogF("CreateFile失败 文件名: %s 行号: %d 错误码: %d",__FILE__,__LINE__,GetLastError());
return;
}
++m_nFileHandle ;
LOG.LogF("文件句柄数目m_nFileHandle: %d 文件名: %s 行号: %d 错误码: %d",m_nFileHandle,__FILE__,__LINE__,WSAGetLastError()); PIOCP_BUF pSendBuffer = AllocateBuffer(0);
memset(&pSendBuffer->ol,0,sizeof(WSAOVERLAPPED));
pSendBuffer->sClient = pContext->s;
pSendBuffer->hSendFile = hFileNew;
//判断文件是否大于2G
pSendBuffer->i64TotalByte = ((INT64)pFile->dwFileSizeHigh << 32) + pFile->dwFileSizeLow;
if ( pSendBuffer->i64TotalByte > 2147483648 ) //文件大于2G
{
//如果大于2G,则先发送2G
pSendBuffer->i64HavedByte = 2147483647;
pSendBuffer->i64PerSendByte = 2147483647;
pSendBuffer->IoOper = IOTransmitFileContinue;
pSendBuffer->ol.OffsetHigh = 0;
++pSendBuffer->nOutTransmitContinue;
if(!m_lpfntransmitfile(pSendBuffer->sClient,hFileNew,2147483647,0, &pSendBuffer->ol,NULL,TF_USE_DEFAULT_WORKER))//TF_USE_KERNEL_APC)) //不能发送2147483648
{
int iError = WSAGetLastError();
if (iError != ERROR_IO_PENDING)
LOG.LogF("m_lpfntransmitfile fail 文件大于2G 客户端Socket: %d 传输文件名: %s 文件名: %s 行号: %d 错误码: %d",pBuffer->sClient,pBuffer->pBuf+4,__FILE__,__LINE__,GetLastError());
}
}
else
{
// 如果小于2G,则发送整个文件
pSendBuffer->i64HavedByte = pSendBuffer->i64TotalByte;
pSendBuffer->i64PerSendByte = pSendBuffer->i64TotalByte;
pSendBuffer->IoOper = IOTransmitFileCompleted;
pSendBuffer->ol.OffsetHigh = 0;
++pSendBuffer->nOutTransmitCompleted;
if(!m_lpfntransmitfile(pSendBuffer->sClient,hFileNew,0,0, &pSendBuffer->ol,NULL,TF_USE_DEFAULT_WORKER))//TF_USE_KERNEL_APC))
{
int iError = WSAGetLastError();
if (iError != ERROR_IO_PENDING)
LOG.LogF("m_lpfntransmitfile fail 文件小于2G 客户端Socket: %d 传输文件名: %s 文件名: %s 行号: %d 错误码: %d",pBuffer->sClient,pBuffer->pBuf+4,__FILE__,__LINE__,GetLastError());
}
}
PostRecv(pContext,pBuffer);
}
建议自己用文件映射,只映射一小部分,然后配合TransmitPackets,结束后重新映射下一部分。
这样内存也能控制住,效率差多少。
On 'CreateFile' you must specify the FILE_FLAG_OVERLAPPED flagThe file must be opened using the FILE_FLAG_OVERLAPPED flag when opened with CreateFile. Else if, the file position pointer is used instead of the overlapped structure, which means that the file will be sent only on the first call. subsequent calls would send only the end of the file.楼主试试看。
http://msdn.microsoft.com/en-us/library/ms740565(VS.85).aspx