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

📄 usortfile.cpp

📁 嵌入式系统的文件下载源码。实现各类文件的无线下载功能
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		if(BytesRead != NULL)
			*BytesRead = -1;
		goto __ENDREAD__;
	}

	// 若 nOffset 大于 0 , 则为指定位置读取数据,否则从文件头部读取
	if ( nOffset >= 0 )
		zfseek (zfp, nOffset, ZSEEK_SET);
	else
	{
	//  参数错误也返回失败
	// 	zfseek (zfp, 0, ZSEEK_SET ); close 2002/12/09
		bRet = FALSE;
		*BytesRead = -1;
		goto __ENDREAD__;
	}
	
	// 读取数据
	nRead = zfread ( ReadBuff, sizeof(char), BytesToRead, zfp);
	if (nRead != (int)BytesToRead)
	{
		bRet = FALSE;
		*BytesRead = nRead;
		goto __ENDREAD__;
	}
	
	*BytesRead = nRead;

__ENDREAD__:
	return bRet;
}

////////////////////////////////////////////////////////////////////////////////////////
// 功能说明 : 在排序文件中进行二分查找,并返回最后一次比对的位移
// 输入参数 : CompBuff		比较缓冲(关键字)
// 输入参数 : nRecOffset	比对(关键字)在记录中的位移
// 输入参数 : nCompBytes	比对(关键字)长度
// 输出参数 : nCompResult	比对结果,-2 代表比对失败,-1 0 1 代表小于等于大于文件位移的记录
// 返回值   : long			最后一次的位移
////////////////////////////////////////////////////////////////////////////////////////
long CSortRecordFile::FindRecord(
								 IN const void *CompBuff,  
								 IN unsigned int nRecOffset,  
								 IN unsigned int nCompBytes,  
								 OUT int *nCompResult 
								 )
{
	char * szReadBuff = NULL ;				// 读取报文缓存
	int nLow = 0;							// 二分查找临时变量 low, high, mid, times.
	int nHight = 0;
	int nMid = 0;
	int nTimes = 0;
	int nRead = 0;							// 读取字节数
	int nCmpRet = 0;						// 比较结果
	int nMaxRecCount = 0;					// 最大记录数
	long nSearchOffset = -1L;				// 返回比较当前位移

/***
 *		准备处理查找, Result = -2 表示非法参数或准备失败
 ***/
	if ( zfp == NULL || CompBuff == NULL || nCompResult == NULL )
	{
		if(nCompResult != NULL)
			*nCompResult = -2;
		return -1L;
	}

	if ( nRecOffset > m_nRecLen )
	{
		*nCompResult = -2;
		return -1L;
	}
	
	szReadBuff = (char*) malloc (sizeof(char) * m_nRecLen + 1 );
	if ( szReadBuff == NULL )
	{
		*nCompResult = -2;
		return -1L;
	}
	else
		memset  (szReadBuff, 0, m_nRecLen + 1);
	
/***
 *		求文件最大记录数
 ***/
	nMaxRecCount = GetRecordCount();
	nHight = nMaxRecCount - 1;
	if ( nHight < 0)
	{
		*nCompResult = -1;
		return 0;
	}

/***
 *		在文件记录中进行二分查找
 ***/
	nTimes = 0;
	while ( ( nTimes < (int)nMaxRecCount ) && ( nLow <= nHight ) )
	{
		nTimes ++ ;
		nMid = ( nLow + nHight ) / 2;

		memset ( szReadBuff , 0 , m_nRecLen + 1 ) ;
		zfseek ( zfp , nMid * ( m_nRecLen  ) + m_nStartOffset, ZSEEK_SET ) ;
		nRead = zfread ( szReadBuff , sizeof(char), (int)m_nRecLen , zfp ) ;
		if ( nRead != (int)m_nRecLen )	// 文件读取失败
		{
			*nCompResult = -2;
			nSearchOffset = -1;
			break;
		}

		/***
		 *		根据比对结果分别对返回值进行赋值
		 ***/
		nCmpRet = memcmp ( CompBuff, szReadBuff+nRecOffset, nCompBytes ) ;
		nSearchOffset = zftell(zfp) - m_nRecLen;
		if ( nCmpRet == 0 )			// CompBuff == szReadBuff+nRecOffset
		{
			*nCompResult = 0;
			break;
		}
		else if ( nCmpRet < 0 )		// CompBuff < szReadBuff+nRecOffset
		{
			*nCompResult = -1;
			nHight = nMid - 1 ;
		}
		else if ( nCmpRet > 0 )		// CompBuff > szReadBuff+nRecOffset
		{	
			*nCompResult = 1;
			nLow = nMid + 1 ;
		}
	}

/***
 *		比对结束,返回结果
 ***/
/*__ENDFIND__:*/
	if(szReadBuff != NULL)
		free(szReadBuff);
	szReadBuff = NULL ;
	
	return nSearchOffset ;
}

////////////////////////////////////////////////////////////////////////////////////////
// 功能说明 : 在缓冲中模糊搜索数据
// 输入参数 : 
// 返回值   : BOOL
////////////////////////////////////////////////////////////////////////////////////////
BOOL CSortRecordFile::BlueSearchData (
							const void *szSrcData, 
							unsigned int nSrcLen, 
							const void *szDestData, 
							unsigned int nDestLen 
							)								 
{
	BOOL bRet = 0;
	char *szSrcStr = NULL;
	char *szDestStr = NULL;

	szSrcStr = (char*) malloc ( sizeof(char)*nSrcLen + 1 );
	szDestStr = (char*) malloc ( sizeof(char)*nDestLen + 1 );

	if ( szSrcStr == NULL || szDestStr == NULL )
	{
		bRet = FALSE;
		goto _END_BLUESEARCHDATA_;
	}

	memset ( szSrcStr, 0, nSrcLen+1 );
	memset ( szDestStr, 0, nDestLen+1 );
	memcpy ( szSrcStr, szSrcData, nSrcLen );
	memcpy ( szDestStr, szDestData, nDestLen );

	if ( strstr(szSrcStr, szDestStr ) != NULL )
		bRet = TRUE;
	else
		bRet = FALSE;

_END_BLUESEARCHDATA_:
	MFree(szSrcStr);
	MFree(szDestStr);

	return bRet;
}

///////////////////////////////////////////////////////////////////////////////////////
// 功能说明 : 在排序文件中进行块读模糊查找,并返回查找到第一条记录的相对位移
// 输入参数 : CompBuff		比较缓冲
// 输入参数 : nRecOffset	比对内容在记录中的相对位移
// 输入参数 : nCompBytes	比对长度
// 输出参数 : nCompResult	比对结果,0 代表查找失败,> 0 表示实际查找到记录条数
// 返回值   : long			查找第一条记录相对位移
////////////////////////////////////////////////////////////////////////////////////////
long CSortRecordFile::BlueSearchRecord (
								 IN const void *szCompBuff,  
								 IN unsigned int nRecOffset,  
								 IN unsigned int nCompBytes,  
								 OUT int *nCompResult 
								 )
{
	
	int nBlockRecCount = 0;
	int nRead = 0;
	int nRecCount = 0;
	long nOffset = 0L;
	long nFileEndOffset = 0L;
	char *szBlockReadBuff=NULL;

	// 能找到则加一,否则为 0
	nCompResult = 0;

	// 申请块读缓冲区, 最大4K
	if ( m_nRecLen > 4096 )
		nBlockRecCount = 1;
	else
		nBlockRecCount = 4096/m_nRecLen;

	szBlockReadBuff = (char*) malloc ( sizeof(char)*(nBlockRecCount)*(m_nRecLen) );
	if(szBlockReadBuff == NULL )
	{
		printf("内存申请失败\n");
		return -1L;
	}
	memset ( szBlockReadBuff, 0, (nBlockRecCount)*(m_nRecLen) );
	
	if (zfp == NULL)
	{
		printf("文件未打开\n");
		return -1L;
	}

	// 从尾部往后倒查文件
	zfseek (zfp, 0, ZSEEK_END);
	nFileEndOffset = zftell(zfp);

	nOffset = -1;
	while (1)
	{
		// 文件长度及尾部位移大于一块长度
		if ( nFileEndOffset >= nBlockRecCount * (int)m_nRecLen )
		{
			nFileEndOffset -= nBlockRecCount * m_nRecLen;
			zfseek ( zfp, nFileEndOffset, ZSEEK_SET );
		}
		else if ( nFileEndOffset > 0 )		// 剩余部分不足一块
		{
			nFileEndOffset = -1;			// 为退出准备条件
			zfseek ( zfp, 0, ZSEEK_SET );
		}
		else
		{
			break;
		}

		memset ( szBlockReadBuff, 0, nBlockRecCount*m_nRecLen );
		nRead = zfread ( szBlockReadBuff, sizeof(char), nBlockRecCount*m_nRecLen, zfp );
		if(nRead <= 0)
			break;
		nRecCount = nRead / m_nRecLen;
		for ( int i = 0; i < nRecCount; i ++ )
		{
			if ( BlueSearchData (szCompBuff, nCompBytes, szBlockReadBuff+i*m_nRecLen+nRecOffset, nCompBytes) )
			{
				nOffset = zftell(zfp) - nRecCount*m_nRecLen + i*m_nRecLen;
				++nCompResult;
				nFileEndOffset = -1;			// 作为结束标志
				break;
			}
		}
	}

	free(szBlockReadBuff);
	szBlockReadBuff=NULL;
	zfclose(zfp);

	return nOffset;
}

								 
////////////////////////////////////////////////////////////////////////////////////////
// 功能说明 : 获取文件记录个数(记录长度为定长)
// 输入参数 : VOID
// 输出参数 : VOID
// 返回值   : int
////////////////////////////////////////////////////////////////////////////////////////
int CSortRecordFile::GetRecordCount (void)
{
	int nRecCount = 0;
	long nFileEndOffset = 0L;

	if ( zfp == NULL || (int)m_nRecLen <= 0 )
		return 0;
	else
		zfclose (zfp);

	zfp = zfopen ( m_szFileName, "r+" );
	if ( zfp == NULL )
		return 0;

	zfseek ( zfp, 0, ZSEEK_END );
	nFileEndOffset = zftell (zfp);
	nFileEndOffset -= m_nStartOffset;
	if (nFileEndOffset < 0 )
		nFileEndOffset = 0;

	nRecCount = 
		nFileEndOffset / m_nRecLen + ((nFileEndOffset % m_nRecLen) ? 1 : 0 ) ;

	return nRecCount;
}

////////////////////////////////////////////////////////////////////////////////////////
// 功能说明 : 获取排序文件总字节数
// 输入参数 : VOID
// 输出参数 : VOID
// 返回值   : long
////////////////////////////////////////////////////////////////////////////////////////
long CSortRecordFile::GetFileBytes (void)
{
	long nFileEndOffset = 0L;
	
	if ( zfp == NULL )
		return 0L;
	else
		zfclose (zfp);

	zfp = zfopen ( m_szFileName, "r+" );
	if ( zfp == NULL )
		return 0L;

	// 获取文件记录长度
	zfseek ( zfp, 0, ZSEEK_END ) ;
	nFileEndOffset = zftell(zfp);
	if ( nFileEndOffset < 0 )
		nFileEndOffset = 0;

	// 返回结果
	return nFileEndOffset;
}

////////////////////////////////////////////////////////////////////////////////////////
// 功能说明 : 把文件在某偏移量后的数据向后移动某偏移量
// 输入参数 : nMoveBeginOffset	开始偏移位置
// 输入参数 : nMoveOffset		移动偏移位置(正代表后移,负代表前移)
// 输出参数 : VOID
// 返回值   : BOOL
// 注意     : 本函数可以较快地移植到其他环境下使用
////////////////////////////////////////////////////////////////////////////////////////
BOOL CSortRecordFile::MoveRecordAfterOffset(
						unsigned long nMoveBeginOffset, 
						long nMoveOffset
						)
{
	int nRead = 0;						// 读取字节
	int nWritten = 0;					// 写入字节
	long nFileBytes = 0L;				// 总字节数
	long nFileBytesToMove = 0L;			// 文件总共需要移动的字节数
	long nBlockToReadBytes = 0L;		// 当前需要读字节数
	long nCurrReadOffset = 0L;			// 当前文件读取文件指针位移
	unsigned char *szBlockReadBuff = NULL;
	BOOL bMoveRet = TRUE;

/***
 *		准备移动数据
 ***/
	// 准备移动文件内容,文件未打开或参数非法返回失败
	if ( zfp == NULL || nMoveOffset == 0 )
	{
		return FALSE;
	}

	// 申请块读缓冲区
	szBlockReadBuff = 
		(unsigned char*) malloc ( sizeof(char)*(RECCNT_PERBLK)*(m_nRecLen) );
	if(szBlockReadBuff == NULL )
	{
		printf  ("malloc memory fail\n");
		return FALSE;
	}

	// 求出总共需要移动的字节数
	nFileBytes = GetFileBytes ();
	if ( nFileBytes == 0 )	// 文件长度为零
	{
		free(szBlockReadBuff);
		return TRUE;
	}

	nFileBytesToMove = nFileBytes - nMoveBeginOffset;
	if ( nFileBytesToMove < 0 )	// 文件长度小于起始位置
	{
		free(szBlockReadBuff);
		return FALSE;
	}
	
/***
 *		根据 nMoveOffset 分别移动数据
 ***/
	// 若位移为负(前移数据)从当前位置开始搬运数据 
	//	* * * | * * * 
	//  1 2 3   4 5 6
	//          <==== 
	if ( nMoveOffset < 0 )

⌨️ 快捷键说明

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