📄 mfile.cpp
字号:
#include "MCRT/mfile.h"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string>
#define INITIALIZED_CHECK() \
if ( this->m_fp == NULL ) \
{\
return 0; \
}
MFile::MFile()
:m_fp(NULL)
{
}
MFile::~MFile()
{
this->Close();
}
mInt32 MFile::Open( const char* pPath, mUInt32 openMode )
{
mInt32 retVal = E_SUCCESS;
//release resouces if has opened
if ( this->m_fp != NULL )
{
this->Close();
}
for ( int iOnce = 0; iOnce < 1; ++ iOnce ) // convenient for releasing resources while failed
{
std::string strMode;
if ( openMode & MFile::MO_RDONLY )
{
//check if file exist
retVal = MFile::Exist( pPath );
if ( retVal != E_SUCCESS )
{
break;
}
strMode.append( "r" );
}
else if ( openMode & MFile::MO_WRONLY )
{
strMode.append( "w" );
}
else if ( openMode & MFile::MO_RDWR )
{
//check if file exist
retVal = MFile::Exist( pPath );
if ( retVal != E_SUCCESS )
{
break;
}
strMode.append( "r" );
}
else if ( openMode & MFile::MO_APPEND )
{
strMode.append( "a" );
}
if ( openMode & MFile::MO_BINARY )
{
strMode.append( "b" );
}
else if ( openMode & MFile::MO_TEXT )
{
strMode.append( "t" );
}
if ( (openMode & MFile::MO_RDWR) || (openMode & MFile::MO_APPEND) )
{
strMode.append( "+" );
}
this->m_fp = ::fopen( pPath, strMode.c_str() );
if ( this->m_fp == NULL )
{
retVal = E_FILE_OPEN;
break;
}
this->m_strPath = pPath;
this->m_mode = openMode;
}
return retVal;
}
mInt32 MFile::Close()
{
if ( this->m_fp != NULL )
{
::fclose( this->m_fp );
this->m_fp = NULL;
}
return E_SUCCESS;
}
bool MFile::IsOpen() const
{
return ( this->m_fp != NULL );
}
mLong MFile::GetLength()
{
INITIALIZED_CHECK();
//save locale
mLong pos = ::ftell( this->m_fp );
mLong posBegin = this->SeekToBegin();
mLong posEnd = this->SeekToEnd();
//restore locale
::fseek( this->m_fp, pos, SEEK_SET );
return posEnd - posBegin;
}
mLong MFile::Seek( mLong offset, MFile::POS_TYPE origin )
{
INITIALIZED_CHECK();
//check if exceeds file length
if( offset+origin > this->GetLength() )
{
return 0;
}
::fseek( this->m_fp, offset, origin );
return this->Tell();
}
mLong MFile::SeekToBegin()
{
INITIALIZED_CHECK();
::rewind( this->m_fp );
return this->Tell();
}
mLong MFile::SeekToEnd()
{
INITIALIZED_CHECK();
::fseek( this->m_fp, 0, SEEK_END );
return this->Tell();
}
mLong MFile::Tell()
{
INITIALIZED_CHECK();
return ::ftell(this->m_fp);
}
mLong MFile::Read( void* pBuf, mLong bufLen )
{
INITIALIZED_CHECK();
mLong bytesRead = 0;
mLong bytesUnit = M_BLOCK_BUF_SIZE;
if ( bufLen > M_BLOCK_BUF_SIZE )
{
mLong countBlock = bufLen / M_BLOCK_BUF_SIZE;
mLong lastBlockSize = bufLen % M_BLOCK_BUF_SIZE;
for ( mLong i = 0; i < countBlock; ++ i )
{
bytesUnit = ::fread( (unsigned char*)pBuf + i*M_BLOCK_BUF_SIZE, sizeof(unsigned char), M_BLOCK_BUF_SIZE, this->m_fp );
bytesRead += bytesUnit;
if ( bytesUnit != M_BLOCK_BUF_SIZE )
{
break;
}
}
if ( (bytesUnit == M_BLOCK_BUF_SIZE) && (lastBlockSize != 0) )
{
bytesRead += ::fread( (unsigned char*)pBuf + countBlock*M_BLOCK_BUF_SIZE, sizeof(unsigned char), lastBlockSize, this->m_fp );
}
}
else
{
bytesRead = ::fread( pBuf, sizeof(unsigned char), bufLen, this->m_fp );
}
return bytesRead;
}
mLong MFile::Write( const void* pBuf, mLong dataLen )
{
INITIALIZED_CHECK();
mLong bytesWrite = 0;
mLong bytesUnit = M_BLOCK_BUF_SIZE;
if ( dataLen > M_BLOCK_BUF_SIZE )
{
mLong countBlock = dataLen / M_BLOCK_BUF_SIZE;
mLong lastBlockSize = dataLen % M_BLOCK_BUF_SIZE;
for ( mLong i = 0; i < countBlock; ++ i )
{
bytesUnit = ::fwrite( (unsigned char*)pBuf + i*M_BLOCK_BUF_SIZE, sizeof(unsigned char), M_BLOCK_BUF_SIZE, this->m_fp );
bytesWrite += bytesUnit;
if ( bytesUnit != M_BLOCK_BUF_SIZE )
{
break;
}
}
if ( (bytesUnit == M_BLOCK_BUF_SIZE) && (lastBlockSize != 0) )
{
bytesWrite += ::fwrite( (unsigned char*)pBuf + countBlock*M_BLOCK_BUF_SIZE, sizeof(unsigned char), lastBlockSize, this->m_fp );
}
}
else
{
bytesWrite = ::fwrite( pBuf, sizeof(unsigned char), dataLen, this->m_fp );
}
return bytesWrite;
}
bool MFile::Flush()
{
if ( this->m_fp != NULL )
{
// fflush no use, so close and reopen
::fclose( this->m_fp );
this->m_fp = NULL;
this->Open( this->m_strPath.c_str(), this->m_mode );
}
return true;
}
mLong MFile::Resize( mLong len )
{
if ( this->m_fp == NULL )
{
return E_FILE_OPEN;
}
char* pBuf = new char[M_BLOCK_BUF_SIZE];
if ( pBuf == NULL )
{
return E_MEMORY_INSUFFICIENT;
}
::memset( pBuf, 0, M_BLOCK_BUF_SIZE );
mLong dataLen = len - this->GetLength();
this->SeekToEnd();
// append blank data to file
mLong bytesWrite = 0;
mLong bytesUnit = M_BLOCK_BUF_SIZE;
if ( dataLen > M_BLOCK_BUF_SIZE )
{
mLong countBlock = dataLen / M_BLOCK_BUF_SIZE;
mLong lastBlockSize = dataLen % M_BLOCK_BUF_SIZE;
for ( mLong i = 0; i < countBlock; ++ i )
{
bytesUnit = ::fwrite( (unsigned char*)pBuf + i*M_BLOCK_BUF_SIZE, sizeof(unsigned char), M_BLOCK_BUF_SIZE, this->m_fp );
bytesWrite += bytesUnit;
if ( bytesUnit != M_BLOCK_BUF_SIZE )
{
break;
}
}
if ( (bytesUnit == M_BLOCK_BUF_SIZE) && (lastBlockSize != 0) )
{
bytesWrite += ::fwrite( (unsigned char*)pBuf + countBlock*M_BLOCK_BUF_SIZE, sizeof(unsigned char), lastBlockSize, this->m_fp );
}
}
else
{
bytesWrite = ::fwrite( pBuf, sizeof(unsigned char), dataLen, this->m_fp );
}
if ( bytesWrite != dataLen )
{
return E_FILE_WRITE;
}
return E_SUCCESS;
}
mInt32 MFile::Exist( const char* pPath )
{
mInt32 retVal = E_SUCCESS;
for ( int iOnce = 0; iOnce < 1; ++ iOnce ) // convenient for releasing resources while failed
{
//check if NULL pointer
if ( pPath == NULL )
{
retVal = E_PARAM_POINTER_NULL;
break;
}
//check if path len exceed system's max path len
if ( ::strlen( pPath ) > PATH_MAX )
{
retVal = E_FILE_PATH_LEN;
break;
}
struct stat fileStat;
//check if file exist
if ( ::stat( pPath, &fileStat ) != 0 )
{
retVal = E_FILE_NOT_EXIST;
break;
}
}
return retVal;
}
mInt32 MFile::Clear( const char* pFile )
{
mInt32 retVal = E_SUCCESS;
for ( int iOnce = 0; iOnce < 1; ++ iOnce ) // convenient for releasing resources while failed
{
//check if file exist
retVal = MFile::Exist( pFile );
if ( retVal != E_SUCCESS )
{
break;
}
MFile mfile;
mfile.Open( pFile, MFile::MO_WRONLY );
mfile.Close();
}
return retVal;
}
mInt32 MFile::Create( const char* pFile, mLong initLen )
{
mInt32 retVal = E_SUCCESS;
MFile mfile;
for ( int iOnce = 0; iOnce < 1; ++ iOnce ) // convenient for releasing resources while failed
{
//check param
if ( pFile == NULL )
{
retVal = E_PARAM_POINTER_NULL;
break;
}
//open and clear file
retVal = mfile.Open( pFile, MFile::MO_WRONLY );
if ( retVal != E_SUCCESS )
{
break;
}
//if initialized length is 0, then is OK
if ( initLen == 0 )
{
break;
}
//add NULL data to file
char* pBuf = new char[initLen];
if ( pBuf == NULL )
{
retVal = E_MEMORY_INSUFFICIENT;
break;
}
::memset( pBuf, 0, initLen );
if ( mfile.Write( pBuf, initLen ) != initLen )
{
retVal = E_FILE_WRITE;
break;
}
delete [] pBuf;
}
if ( mfile.IsOpen() )
{
mfile.Close();
}
return retVal;
}
mInt32 MFile::Compare( const char* pDestFile, const char* pSrcFile )
{
mInt32 retVal = E_SUCCESS;
MFile mfileSrc;
MFile mfileDest;
char* pBufSrc = NULL;
char* pBufDest= NULL;
struct stat srcFileStat;
struct stat destFileStat;
mLong bytesUnit = 0;
for ( int iOnce = 0; iOnce < 1; ++ iOnce ) // convenient for releasing resources while failed
{
//check file whether exists
retVal |= MFile::Exist( pDestFile );
retVal |= MFile::Exist( pSrcFile );
if ( retVal != E_SUCCESS )
{
break;
}
//check file size first, previous exist assure ::stat success
::stat( pSrcFile, &srcFileStat );
::stat( pDestFile, &destFileStat );
if ( srcFileStat.st_size != destFileStat.st_size )
{
retVal = E_GENERAL;
break;
}
//open file
retVal = mfileSrc.Open( pSrcFile, MFile::MO_RDONLY );
retVal = mfileDest.Open( pDestFile, MFile::MO_RDONLY );
if ( retVal != E_SUCCESS )
{
break;
}
//allocate compare resources
pBufSrc = new char[M_BLOCK_BUF_SIZE];
pBufDest= new char[M_BLOCK_BUF_SIZE];
if ( (pBufSrc == NULL) || (pBufDest == NULL) )
{
retVal = E_MEMORY_INSUFFICIENT;
break;
}
//check if the contents are same
bytesUnit = 0;
while ( (bytesUnit = mfileSrc.Read( pBufSrc, M_BLOCK_BUF_SIZE )) > 0 )
{
mfileDest.Read( pBufDest, M_BLOCK_BUF_SIZE );
if ( ::memcmp( pBufDest, pBufSrc, bytesUnit ) != 0 )
{
retVal = E_GENERAL;
break;
}
}
}
mfileSrc.Close();
mfileDest.Close();
delete [] pBufSrc;
delete [] pBufDest;
return retVal;
}
mInt32 MFile::Copy( const char* pDestFile, const char* pSrcFile )
{
mInt32 retVal = E_SUCCESS;
MFile fileDest, fileSrc;
char* pBuf = NULL;
mInt32 dataRead = 0;
for ( int iOnce = 0; iOnce < 1; ++ iOnce ) // convenient for releasing resources while failed
{
if ( (pDestFile == NULL) || (pSrcFile == NULL) )
{
retVal = E_PARAM_POINTER_NULL;
break;
}
retVal = fileDest.Open( pDestFile, MFile::MO_WRONLY | MFile::MO_BINARY );
if ( retVal != E_SUCCESS )
{
break;
}
retVal = fileSrc.Open( pSrcFile, MFile::MO_RDONLY | MFile::MO_BINARY );
if ( retVal != E_SUCCESS )
{
break;
}
pBuf = new char[M_BLOCK_BUF_SIZE];
if ( pBuf == NULL )
{
retVal = E_MEMORY_INSUFFICIENT;
break;
}
dataRead = fileSrc.Read( pBuf, M_BLOCK_BUF_SIZE );
while ( dataRead > 0 )
{
if ( fileDest.Write( pBuf, dataRead ) != dataRead )
{
retVal = E_FILE_WRITE;
break;
}
dataRead = fileSrc.Read( pBuf, M_BLOCK_BUF_SIZE );
}
}
fileDest.Close();
fileSrc.Close();
delete [] pBuf;
return retVal;
}
mLong MFile::Read( const char* pFile, mLong offset, void* pBuf, mLong bufLen )
{
mLong dataRead = 0;
for ( int iOnce = 0; iOnce < 1; ++ iOnce ) // convenient for releasing resources while failed
{
MFile mfile;
if ( mfile.Open( pFile, MFile::MO_RDONLY | MFile::MO_BINARY ) != E_SUCCESS )
{
break;
}
if ( mfile.Seek( offset, MFile::MPOS_BEGIN ) != offset )
{
break;
}
dataRead = mfile.Read( pBuf, bufLen );
}
return dataRead;
}
mLong MFile::Write( const char* pFile, mLong offset, void* pBuf, mLong dataLen )
{
mLong dataWrite = 0;
for ( int iOnce = 0; iOnce < 1; ++ iOnce ) // convenient for releasing resources while failed
{
MFile mfile;
if ( mfile.Open( pFile, MFile::MO_RDWR | MFile::MO_BINARY ) != E_SUCCESS )
{
break;
}
if ( mfile.Seek( offset, MFile::MPOS_BEGIN ) != offset )
{
break;
}
dataWrite = mfile.Write( pBuf, dataLen );
}
return dataWrite;
}
mLong MFile::Append( const char* pFile, const void* pBuf, mLong dataLen )
{
mLong dataWrite = 0;
for ( int iOnce = 0; iOnce < 1; ++ iOnce ) // convenient for releasing resources while failed
{
MFile mfile;
if ( mfile.Open( pFile, MFile::MO_APPEND | MFile::MO_BINARY ) != E_SUCCESS )
{
break;
}
dataLen = mfile.Write( pBuf, dataLen );
}
return dataWrite;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -