1、C++基礎:數據流、緩沖區、文件類型
●數據流stream:程序與數據間的交互是以流的形式進行的,文件存取時都會先進行 “打開文件” 的操作,目的是打開數據流,而“關閉文件”操作就是關閉數據流。
●緩沖區Buffer:程序執行時提供額外的內存以暫時存放數據。緩沖區的作用是提高存取效率,因為內存的存取速率比磁盤快。
●文件類型:分為文本文件和二進制文件。
文本文件:字符編碼的形式進行保存。
二進制文件:內存中的數據原封不動至文件中,適用於非字符為主的數據。優點:存取速度快,占用空間小。
2、文件讀寫流程
文件數據讀取時,先打開數據流,將磁盤上的文件信息拷貝到緩沖區內,然后再從緩沖區中讀取所需數據;
當數據寫入文件時,先將數據寫入緩沖區,只有在緩沖區已滿或“關閉文件”后,才會將數據寫入磁盤;
2.1 、常用函數
打開文件:errno_t fopen_s( FILE** pFile, const char *filename, const char *mode );//打開文件,如果成功返回0
參數說明: pFile:文件指針
filename:文件名
mode:允許訪問的類型
讀取文件:size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ;//它從文件流中讀數據,最多讀取count個項,每個項size個字節,如果調用成功返回實際讀取到的項個數(小於或等於count)
參數說明:buffer :用於接收數據的內存地址
size : 要讀取的每個數據項的字節數
count : 要讀取count個數據,每個數據size個字節
stream : 要讀取的文件指針
寫文件:size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);//返回實際寫入的數據項的個數
參數說明:buffer : 是一個指針,要獲取的數據的地址
size : 要寫入內容的單字節數
count : 要進行寫入size字節的數據項的個數
stream : 目標文件指針
int main() { FILE *file = nullptr; std::shared_ptr<short> spVolCTValue(new short [20447232],[](short *p){delete []p;}); if (fopen_s(&file, "E://Colon.raw", "rb") == 0) { size_t nCount = fread(spVolCTValue.get(), sizeof(short),20447232, file); nCount; fclose(file); } std::shared_ptr<McsfAlgoVirtualColonoscopy> spAlgoVirtualColonoscopy; int iDim[3]={512,512,78}; float fSpacing[3] = {0.58593750,0.58593750,3.0}; bool bStool = false; spAlgoVirtualColonoscopy.reset(new McsfAlgoVirtualColonoscopy(spVolCTValue.get()/*pData*/, iDim, fSpacing)); spAlgoVirtualColonoscopy->ColonSegmentation(true, bStool); return 0; }
bool StaObjectColonVolumeData::CreatAlgoVirtualColonoscopy( ) { auto spImageData = getImgData(); std::shared_ptr<short> spVolCTValue; int iDim[3]; spImageData->GetDimension(iDim); double dSpacing[3]; spImageData->GetSpacing(dSpacing); float fSpacing[3] = {static_cast<float>(dSpacing[0]), static_cast<float>(dSpacing[1]), static_cast<float>(dSpacing[2])}; std::array<size_t,3> arrDim = spImageData->GetDimension(); m_spVolCTValue = ModalityUtility::TransformToCTValue(spImageData, arrDim, m_bIsReverse); FILE* file = nullptr; fopen_s(&file, "E://Colon.raw","wb"); size_t count = fwrite(spVolCTValue.get(),sizeof(short),iDim[0]*iDim[1]*iDim[2],file); fclose(file); m_spAlgoVirtualColonoscopy.reset(new McsfAlgoVirtualColonoscopy(m_spVolCTValue.get(), iDim, fSpacing)); return true; }
第二種讀取文件的方式:ofstream,ifstream, fstream
- #include <fstream>
- ofstream //文件寫操作 內存寫入存儲設備
- ifstream //文件讀操作,存儲設備讀區到內存中
- fstream //讀寫操作,對打開的文件可進行讀寫操作
打開文件:
在fstream中,成員函數open()實現打開文件的操作,從而將數據流和文件進行關聯。
open(const char *_Filename, std::ios_base::openmode);
參數說明:_Filename :要打開的文件名
openmode : 打開方式(下面的方式是能夠進行組合使用的,以“或”運算(“|”)的方式)
讀寫文件:write ( char * buffer, streamsize size );
read ( char * buffer, streamsize size );
參數說明:buffer : 是一塊內存,用來存取或讀出數據
size :一個整數值,表示要從緩存(buffer)中讀出或寫入的字符數
寫文件舉例:
bool StaObjectColonVolumeData::CreatAlgoVirtualColonoscopy( ) { auto spImageData = getImgData(); int iDim[3]; spImageData->GetDimension(iDim); double dSpacing[3]; spImageData->GetSpacing(dSpacing); float fSpacing[3] = {static_cast<float>(dSpacing[0]), static_cast<float>(dSpacing[1]), static_cast<float>(dSpacing[2])}; std::array<size_t,3> arrDim = spImageData->GetDimension(); m_spVolCTValue = ModalityUtility::TransformToCTValue(spImageData, arrDim, m_bIsReverse); fstream fileout; fileout.open("E://Colon.raw", std::ios::binary|std::ios::out); //上兩句可以合並成:fstream fileout( "E://Colon.raw", std::ios::binary|std::ios::out);
//或者 ofstream fileout("E://Colon1.raw", std::ios::binary|std::ios::out); fileout.write((char*)(m_spVolCTValue.get()), iDim[0]*iDim[1]*iDim[2]*sizeof(short) ); fileout.close(); m_spAlgoVirtualColonoscopy.reset(new McsfAlgoVirtualColonoscopy(m_spVolCTValue.get(), iDim, fSpacing)); return true; }
讀文件舉例:
int main() { std::shared_ptr<short> spVolCTValue(new short [20447232],[](short *p){delete []p;}); ifstream in("E://Colon.raw", std::ios::binary|std::ios::in); in.read((char *)spVolCTValue.get(),20447232*sizeof(short)); std::shared_ptr<McsfAlgoVirtualColonoscopy> spAlgoVirtualColonoscopy; int iDim[3]={512,512,78}; float fSpacing[3] = {0.58593750,0.58593750,3.0}; bool bStool = false; spAlgoVirtualColonoscopy.reset(new McsfAlgoVirtualColonoscopy(spVolCTValue.get()/*pData*/, iDim, fSpacing)); spAlgoVirtualColonoscopy->ColonSegmentation(true, bStool); return 0; }