|
别人研究红外视屏,从红外视屏里得到有180个TXT文件,一个文件对应一个frame的像素,每个文件有512*640个4位数的数字,一个文件大小1.56MB,180个文件是281MB,如图,要求把这些文件对应位置上的数字加起来写到列外一个文件,看到他们用C语言fopen、fscanf运行程序运行了快一个小时。。。。。。
然后用内存映射读取文件,试着加了三个文件,运行快十秒钟的样子,180个文件9分钟。。。。
程序界面:
主要代码:
void CplusDlg::OnBnClickedOk()
{
CMemMapFile m_mmf;
CMemMapFile m_mmfdata;
CString szTmp;
CString szTmpfile;
//TCHAR pszTmpFile[_MAX_PATH];
CMemMapFile m_mmdstfile;
CString szdstFile;
CString szdstTmp;
CFileFind find;
CFileStatus fs;
TCHAR *tokenPtr = NULL;
TCHAR *next_token = NULL;
TCHAR *tokenPtr2 = NULL;
TCHAR *next_token2 = NULL;
TCHAR delims[] = _T(" ,\t\r\n");
BOOL bSuccess; //
LPVOID lpData = NULL ;
LPVOID lpdstData = NULL;
LPVOID lpfData = NULL;
LONG number=0;
LONG number2=0;
BeginWaitCursor();
UpdateData();
if (m_dstFile.IsEmpty())
{
szdstFile = _T("E:\\cegr01923.txt");
}else{
szdstFile = m_dstFile;
}
UpdateData(FALSE);
szTmp = m_Path;
szTmp +=_T("\\*.txt");
bSuccess = find.FindFile(szTmp);
m_listTxt.ResetContent();
BOOL bFirst;
bFirst = TRUE;
szTmp=_T("");
while(bSuccess )
{
bSuccess = find.FindNextFile();
CString file = find.GetFilePath();
m_listTxt.AddString(file);
if (file.IsEmpty()) return;
if (bFirst)
{
VERIFY(CopyFile(file, szdstFile, FALSE));
bFirst = FALSE;
continue;
}
//backup
GetuniqueTempName(szTmpfile);
//_stprintf_s(pszTmpFile, MAX_PATH, _T("%s"), szTmpfile);
VERIFY(CopyFile(file, szTmpfile, FALSE));
m_mmfdata.MapFile(szTmpfile,FALSE);
lpfData = m_mmfdata.Open();
ASSERT(lpfData);
VERIFY(CFile::GetStatus(szTmpfile, fs));
ASSERT(fs.m_size <= ULONG_MAX);
///
GetuniqueTempName(szdstTmp);
VERIFY(CopyFile(szdstFile, szdstTmp, FALSE));
m_mmf.MapFile(szdstTmp);
lpData = m_mmf.Open();
ASSERT(lpData);
VERIFY(CFile::GetStatus(szdstTmp, fs));
ASSERT(fs.m_size <= ULONG_MAX);
// m_mmdstfile.MapFile(szdstFile,FALSE,FALSE,NULL,NULL,TRUE,0);
// lpdstData = m_mmdstfile.Open();
// ASSERT(lpdstData);
// VERIFY(CFile::GetStatus(szdstFile, fs));
// ASSERT(fs.m_size <= ULONG_MAX);
// if (lpdstData)
// memset(lpdstData,0, static_cast<size_t>(fs.m_size));
CFile m_dstFile(szdstFile,CFile::modeCreate|CFile::modeWrite);
m_dstFile.SetLength(0);
tokenPtr=_tcstok_s(static_cast<TCHAR *>(lpfData),delims,&next_token); //strtok_s会修改原字符串
tokenPtr2=_tcstok_s(static_cast<TCHAR *>(lpData),delims,&next_token2); //strtok_s会修改原字符串
while(tokenPtr!=NULL && tokenPtr2!=NULL)
{
CString ss;
if (tokenPtr != NULL)
{
//tokenPtr to int(number)
ss.Format(_T("%s"),tokenPtr);
number = _tcstol(ss,NULL,10); //其实可以直接用tokenPtr to number,但是UNICODE时第一个为0
if (number > 5000)
{
number -= 5000;
}
tokenPtr=_tcstok_s(NULL,delims,&next_token);
}
if (tokenPtr2 != NULL)
{
//tokenPtr2 to int(number2)
ss.Format(_T("%s"),tokenPtr2); ss.Trim();
number2 = _tcstol(ss,NULL,10);
if (number2 > 5000)
{
number2 -= 5000;
}
number2 +=number;
//write data to file "szdatfile"
ss.Format(_T("%d "),number2);
ss.TrimLeft();
//memcpy((TCHAR*)(lpdstData),ss,ss.GetLength());
//_tcscat((TCHAR *)(lpdstData),ss);
m_dstFile.Write(ss,ss.GetLength());
tokenPtr2=_tcstok_s(NULL,delims,&next_token2);
}
} //end for strtok
m_dstFile.Close();
// m_mmdstfile.Flush();
// m_mmdstfile.UnMap();
// m_mmdstfile.Close();
DeleteFile(szTmpfile);
DeleteFile(szdstTmp);
m_mmfdata.UnMap();
m_mmfdata.Close();
m_mmf.UnMap();
m_mmf.Close();
}
EndWaitCursor();
}
其中CMemMapFile是内存映射用封装的MFC类。。()
|
|