最近遇到一个问题,要同时读500个文件,每个50kbyte/s一般的硬盘照理说是能读到的25M/s的不过在客户机器上老读不到,是用2~6个thread, fread 来读取的只能最多10M/s 硬盘是一个1200G scsi 硬盘,可以热插拔那种我的程序开2个一共读10M/s ,然后用HD Tune测试,还可以读3M/s平均请问用完成端口能快点不?或者有什么窍门能快点呢?多谢,多谢做过VOD的,能否点拨一二,非常谢谢

解决方案 »

  1.   

    使用缓存,快速文件系统复制,然后多线程。可以参考以下程序:UINT ThreadProc(LPVOID pParam)
    {
    CQuickFileSystemDlg *L=(CQuickFileSystemDlg*)pParam;
    L->workFunc(); return 0;
    }void CQuickFileSystemDlg::workFunc()
    {
    int j,i;
    void (*f[5])(TCHAR*)={f1,f2,f3,f4,f5};
    CString strText,strTmp[2];
    buffer=new TCHAR[BUFFER_SIZE];
    DWORD Tick;
    DWORD NoBufferTotalTime=0,NoBufferEndTime;
    DWORD SequenTotalTime=0,SequenEndTime;
    DWORD OverlpTotalTime=0,OverlpEndTime;
    DWORD NoBufferAverageTime=0;
    DWORD SequenAverageTime=0;
    DWORD OverlpAverageTime=0; j=0;
    showResult("→无文件高速缓存模式开始.");
    for(i=0;i<10;i++)
    {
    if(i==0) strTmp[0]="source.txt";
    else strTmp[0].Format("nobuffer%d.txt",i);
    strTmp[1].Format("nobuffer%d.txt",i+1);
    Tick=GetTickCount();
    if(!pFile_NoBuffer(strTmp[0],strTmp[1],f[j])) return;
    NoBufferEndTime=GetTickCount();
    NoBufferTotalTime+=NoBufferEndTime-Tick;
    strText.Format("无缓存  %d-%d: %d ms",i,i+1,NoBufferEndTime-Tick);
    if(j++ == 4) j=0;
    showResult(strText);
    }
    showResult("→无文件高速缓存模式结束.",1); j=0;
    showResult("→使用文件高速缓存模式开始.");
    for(i=0;i<10;i++)
    {
    if(i==0) strTmp[0]="source.txt";
    else strTmp[0].Format("sequen%d.txt",i);
    strTmp[1].Format("sequen%d.txt",i+1);
    Tick=GetTickCount();
    if(!pFile_Sequen(strTmp[0],strTmp[1],f[j])) return;
    SequenEndTime=GetTickCount();
    SequenTotalTime+=SequenEndTime-Tick;
    strText.Format("使用缓存  %d-%d: %d ms",i,i+1,SequenEndTime-Tick);
    if(j++ == 4) j=0;
    showResult(strText);
    }
    showResult("→使用文件高速缓存模式结束.",1); j=0;
    showResult("→异步传输模式开始.");
    for(i=0;i<10;i++)
    {
    if(i==0) strTmp[0]="source.txt";
    else strTmp[0].Format("overlp%d.txt",i);
    strTmp[1].Format("overlp%d.txt",i+1);
    Tick=GetTickCount();
    if(!pFile_Overlp(strTmp[0],strTmp[1],f[j])) return;
    OverlpEndTime=GetTickCount();
    OverlpTotalTime+=OverlpEndTime-Tick;
    strText.Format("异步传输  %d-%d: %d ms",i,i+1,OverlpEndTime-Tick);
    if(j++ == 4) j=0;
    showResult(strText);
    }
    showResult("→异步传输模式结束.",1);
    delete []buffer; showResult("→三种模式下的平均时间以做对比:");
    strText.Format("·无文件高速缓存模式平均用时: %d ms",NoBufferTotalTime/10);
    showResult(strText);
    strText.Format("·使用文件高速缓存模式平均用时: %d ms",SequenTotalTime/10);
    showResult(strText);
    strText.Format("·异步传输模式平均用时: %d ms",OverlpTotalTime/10);
    showResult(strText);
    }void CQuickFileSystemDlg::showResult(CString strText,int nReturn)
    {
    CString strEdit;
    m_ShowResult.GetWindowText(strEdit);  
    m_ShowResult.SetFocus();  
    m_ShowResult.SetSel(strEdit.GetLength(),strEdit.GetLength());
    //m_ShowResult.SetSel(-1,-1);
    m_ShowResult.ReplaceSel(strText+"\n");
    for(int i=0;i<nReturn;i++)
    {
    m_ShowResult.GetWindowText(strEdit);  
    m_ShowResult.SetFocus();  
    m_ShowResult.SetSel(strEdit.GetLength(),strEdit.GetLength());
    m_ShowResult.ReplaceSel("\n");
    }
    //UpdateData(TRUE);
    }BOOL CQuickFileSystemDlg::pFile_NoBuffer(CString pSource,CString pSink,void (*func)(TCHAR* addr))
    {
    HANDLE handle_src,handle_dst;
    BOOL cycle=TRUE;
    DWORD NumberOfBytesRead,NumberOfBytesWrite,index; handle_src=CreateFile(pSource,GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_FLAG_NO_BUFFERING,NULL); handle_dst=CreateFile(pSink,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,NULL,NULL); if(handle_src==INVALID_HANDLE_VALUE)
    {
    showResult("打开源文件“"+pSource+"”错误!终止。");
    return FALSE;
    }
    else if(handle_dst==INVALID_HANDLE_VALUE)
    {
    showResult("创建目标文件“"+pSink+"”错误!终止。");
    return FALSE;
    } while(cycle)
    {
    if(!ReadFile(handle_src,buffer,BUFFER_SIZE,&NumberOfBytesRead,NULL))
    {
    showResult("读取文件“"+pSource+"”错误!终止。");
    return FALSE;
    } if(NumberOfBytesRead<BUFFER_SIZE) cycle=FALSE; for(index=0;index<NumberOfBytesRead;index++) func(&buffer[index]); if(!WriteFile(handle_dst,buffer,NumberOfBytesRead,&NumberOfBytesWrite,NULL))
    {
    showResult("写文件“"+pSink+"”错误!终止。");
    return FALSE;
    }
    } CloseHandle(handle_src);
    CloseHandle(handle_dst);
    return TRUE;
    }BOOL CQuickFileSystemDlg::pFile_Sequen(CString pSource,CString pSink,void (*func)(TCHAR* addr))
    {
    HANDLE handle_src,handle_dst;
    BOOL cycle=TRUE;
    DWORD NumberOfBytesRead,NumberOfBytesWrite,index; handle_src=CreateFile(pSource,GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);
    handle_dst=CreateFile(pSink,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,FILE_FLAG_SEQUENTIAL_SCAN,NULL); if(handle_src==INVALID_HANDLE_VALUE)
    {
    showResult("打开源文件“"+pSource+"”错误!终止。");
    return FALSE;
    }
    else if(handle_dst==INVALID_HANDLE_VALUE)
    {
    showResult("创建目标文件“"+pSink+"”错误!终止。");
    return FALSE;
    } while(cycle)
    {
    if(!ReadFile(handle_src,buffer,BUFFER_SIZE,&NumberOfBytesRead,NULL))
    {
    showResult("读取文件“"+pSource+"”错误!终止。");
    return FALSE;
    } if(NumberOfBytesRead<BUFFER_SIZE) cycle=FALSE; for(index=0;index<NumberOfBytesRead;index++) func(&buffer[index]); if(!WriteFile(handle_dst,buffer,NumberOfBytesRead,&NumberOfBytesWrite,NULL))
    {
    showResult("写文件“"+pSink+"”错误!终止。");
    return FALSE;
    }
    } CloseHandle(handle_src);
    CloseHandle(handle_dst);
    return TRUE;
    }BOOL CQuickFileSystemDlg::pFile_Overlp(CString pSource,CString pSink,void (*func)(TCHAR* addr))
    {
    HANDLE handle_src,handle_dst;
    BOOL cycle=TRUE;
    DWORD NumberOfBytesRead,NumberOfBytesWrite,index,dwError;
    OVERLAPPED overlapped; handle_src=CreateFile(pSource,GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_FLAG_NO_BUFFERING|FILE_FLAG_OVERLAPPED,NULL);
    handle_dst=CreateFile(pSink,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,NULL,NULL); if(handle_src==INVALID_HANDLE_VALUE)
    {
    showResult("打开源文件“"+pSource+"”错误!终止。");
    return FALSE;
    }
    else if(handle_dst==INVALID_HANDLE_VALUE)
    {
    showResult("创建目标文件“"+pSink+"”错误!终止。");
    return FALSE;
    } overlapped.hEvent=NULL;
    overlapped.Offset=-BUFFER_SIZE;
    overlapped.OffsetHigh=0; while(cycle)
    {
    overlapped.Offset=overlapped.Offset+BUFFER_SIZE; if(!ReadFile(handle_src,buffer,BUFFER_SIZE,&NumberOfBytesRead,&overlapped))
    {
    switch(dwError=GetLastError())
    {
    case ERROR_HANDLE_EOF:
    cycle=FALSE;
    break;
    case ERROR_IO_PENDING:
    if(!GetOverlappedResult(handle_src,&overlapped,&NumberOfBytesRead,TRUE))
    {
    showResult("异步读文件“"+pSource+"”错误!终止。");
    return FALSE;
    }
    break;
    default:
    break;
    }
    } if(NumberOfBytesRead<BUFFER_SIZE) cycle=FALSE; for(index=0;index<NumberOfBytesRead;index++) func(&buffer[index]); if(!WriteFile(handle_dst,buffer,NumberOfBytesRead,&NumberOfBytesWrite,NULL))
    {
    showResult("写文件“"+pSink+"”错误!终止。");
    return FALSE;
    }
    } CloseHandle(handle_src);
    CloseHandle(handle_dst);
    return TRUE;
    }void CQuickFileSystemDlg::OnStart() 
    {
    CWinThread *m_pThread;
    m_pThread=AfxBeginThread(ThreadProc,this);
    ASSERT(m_pThread);
    m_pThread->m_bAutoDelete=TRUE;
    m_pThread->ResumeThread();
    }
      

  2.   

    不要迷信内存映射
    不管直接用ReadFile还是文件映射,在内部都是通过ReadFile来实现,只不过这此细节被操作系统隐藏起来,目的就是为了操作方便。
      

  3.   

    这跟内存映射有什么关系?
    SCSI硬盘本身的优势就是并发读写,而不是连续读写
    按指定的速度执行
    你需要在线程里执行速度控制,计算开始读的时间和结束时间,不到1秒,就SLEEP掉应该使用多线程读,因为SCSI和IDE或者SATA硬盘不一样,SCSI硬盘你采用1-2个线程几个顺序读的话,等于没利用它的并发性能,建议开到4-8个并发读另外一个没看清楚,为什么采用 NO BUFFER模式? 你是设置无缓冲吗? 那会导致性能直线下降
      

  4.   

    to danscort2000(danscort.yu)
    我是直接用fopen读的,无缓冲是另外一个人给的代码