⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 transactionfile.cpp

📁 该代码是将MSDN中的httpsvr MFC代码移植到STL。含有VC完整应用程序代码。
💻 CPP
字号:
// TransactionFile.cpp: implementation of the TransactionFile class.
//
//////////////////////////////////////////////////////////////////////

#include "StdAfx.h"
#include "TransactionFile.h"


#include <sstream>
using namespace std;

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


/////////////////////////////////////////////////////////////
// operator <<
//
// Purpose:		stream operators for file

void operator << ( stringstream & strm, TransactionFile & file )
{
	// get buffer
	long	sz     = file.size();
	TCHAR * buffer = new TCHAR[sz+1];
	if ( !buffer )
		return;

	// if read in, put buffer into stream
	if ( file.read(buffer,sz) )
	{
		buffer[sz] = '\0';
		strm << buffer;
	}

	// release buffer
	delete buffer;
}

void operator << ( TransactionFile & file, stringstream & strm )
{
	// get buffer
	long    sz     = strm.str().size();
	TCHAR * buffer = (TCHAR *) strm.str().c_str();
	if ( !buffer )
		return;

	// write buffer to file
	file.write(buffer,sz);
}


/////////////////////////////////////////////////////////////
// TransactionFile



TransactionFile::TransactionFile () :
	Lock(),
	SysEvent(),
	m_hFile(0),						// handle to file
	m_readOffset(0),				// current read offset
	m_writeOffset(0),				// current write offset
	m_readWait(INFINITE),			// time (ms) to wait after read
	m_writeWait(INFINITE),			// time (ms) to wait after write
	m_openFlags(0),					// flags used to open file
	m_name("")						// name of file

{
	SysEvent::create();
}

TransactionFile::~TransactionFile () 
{
	destroyLock();
	SysEvent::release();
	close();
}


void TransactionFile::showLastError ()
{
	LPVOID lpMsgBuf;
	DWORD  error = GetLastError();
	FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | 
				   FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,    
				   NULL,
				   error,
				   MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
				   (LPTSTR) &lpMsgBuf,    0,    NULL );		  // Process any inserts in lpMsgBuf.

	// Display the string.
	AtlTrace("%s\n",(const char *) lpMsgBuf);

	// Free the buffer.
	LocalFree( lpMsgBuf );
}



bool TransactionFile::invalidFile ()
{
	if ( m_hFile == INVALID_HANDLE_VALUE )
		return true;
	else
		return false;
}

bool TransactionFile::create ( string & fileName )
{
	DWORD openFlags = CREATE_ALWAYS;
	return open(fileName,openFlags);
}

bool TransactionFile::open ( string & fileName )
{
	DWORD openFlags = OPEN_ALWAYS;
	return open(fileName,openFlags);
}


bool TransactionFile::openAlways ( string & fileName )
{
	DWORD openFlags = OPEN_ALWAYS;
	return open(fileName,openFlags);
}

bool TransactionFile::open ( string & fileName, DWORD openFlags )
{
	if ( !lock() )
		return false;

	// open the file
	m_hFile = 
	CreateFile( fileName.c_str(),
				GENERIC_READ | GENERIC_WRITE,
				FILE_SHARE_READ | FILE_SHARE_WRITE,
				NULL,
				openFlags,
				FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 
				0 );

	unlock();

	if ( m_hFile == INVALID_HANDLE_VALUE )
	{
		showLastError();
		return false;
	}

	// store file info
	m_openFlags = openFlags;
	m_name = fileName;
	m_readOffset = 0;
	m_writeOffset = 0;

	return true;
}

void TransactionFile::close ()
{
	if ( !lock() )
		return;

	if ( m_hFile == INVALID_HANDLE_VALUE )
		return;

	::CloseHandle(m_hFile);
	m_hFile = INVALID_HANDLE_VALUE;

	unlock();
}


bool TransactionFile::offsetPosition ( DWORD offset, bool read )
{
	if ( !lock() )
		return false;

	if ( m_hFile == INVALID_HANDLE_VALUE )
		return false;

	if ( read )
		m_readOffset  += offset;
	else
		m_writeOffset += offset;

	unlock();
	return true;
}


bool TransactionFile::setPosition ( DWORD position, bool read )
{
	if ( !lock() )
		return false;

	if ( m_hFile == INVALID_HANDLE_VALUE )
		return false;

	if ( read )
		m_readOffset  = position;
	else
		m_writeOffset = position;

	unlock();
	return true;
}


void TransactionFile::clear ()
{
	if ( !lock() )
		return;

	if ( m_hFile == INVALID_HANDLE_VALUE )
		return;

	::CloseHandle(m_hFile);
	DeleteFile( m_name.c_str() );

	bool success = 
	open(m_name,m_openFlags);

	unlock();
}

long TransactionFile::size ()
{
	if ( !lock() )
		return 0;

	if ( m_hFile == INVALID_HANDLE_VALUE )
		return 0;

	DWORD dwSize =
	::GetFileSize(m_hFile, NULL);

	unlock();
	return dwSize;
}

bool TransactionFile::write ( LPTSTR pBuffer, DWORD noToWrite, bool wait )
{
	if ( !lock() )
		return false;

	// set overlap for write
	OVERLAPPED overlap;

	HANDLE hEvent      = getEvent();
	overlap.hEvent     = hEvent;
	overlap.Offset     = m_writeOffset;
	overlap.OffsetHigh = 0;

	bool success = false;
	try
	{
		// write to file
		DWORD noWritten = 0;
		if ( WriteFile(m_hFile,(LPVOID)pBuffer,noToWrite,&noWritten,&overlap) != 0 )
			success = true;

		if ( wait && m_writeWait > 0 )
		{
			DWORD result = WaitForSingleObject( hEvent, m_writeWait );
			switch ( result )
			{
				case WAIT_OBJECT_0:
					break;

				case WAIT_ABANDONED:
				case WAIT_TIMEOUT:
				default:
					return false;

			}
		}

		// if write success update write offset
		if ( noWritten == noToWrite )
			m_writeOffset += noWritten;

	}
	catch(...)
	{}


	unlock();

	return success;
}

bool TransactionFile::read ( LPTSTR pBuffer, DWORD noToRead, bool wait )
{
	//if ( !lock() )
	//	return false;

	// set overlap for write
	OVERLAPPED overlap;

	HANDLE hEvent      = getEvent();
	overlap.hEvent     = hEvent;
	overlap.Offset     = m_readOffset;
	overlap.OffsetHigh = 0;

	bool success = false;
	try
	{
		// read from file
		DWORD noRead;
		DWORD result = ReadFile(m_hFile,(LPVOID)pBuffer,noToRead,&noRead,&overlap);
		if ( result != 0 )
			success = true;

		if ( wait && m_readWait > 0 )
		{
			DWORD result = WaitForSingleObject( hEvent, m_readWait );
			switch ( result )
			{
				case WAIT_OBJECT_0:
					break;

				case WAIT_ABANDONED:
				case WAIT_TIMEOUT:
				default:
					return false;

			}
		}

		// if read success update read offset 
		if ( noRead == noToRead )
			m_readOffset += noRead;

	}
	catch(...)
	{}

	unlock();

	return success;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -