📄 usortfile.cpp
字号:
{
if ( (long)(nMoveBeginOffset - (0-nMoveOffset)) < 0 ) // 前移位置超出文件首部
{
free(szBlockReadBuff);
return FALSE;
}
// 初始化变量,文件指针位置
nCurrReadOffset = nMoveBeginOffset;
// 开始移动
while (1)
{
// 剩余需要移动的数据大于一块长度
if ( nFileBytesToMove >= (long)(RECCNT_PERBLK * m_nRecLen) )
{
nBlockToReadBytes = RECCNT_PERBLK * m_nRecLen;
nFileBytesToMove -= RECCNT_PERBLK * m_nRecLen;
}
// 剩余需要移动的数据小于一块但大于零
else if ( nFileBytesToMove > 0 )
{
nBlockToReadBytes = nFileBytesToMove;
nFileBytesToMove = 0; // 准备退出条件
}
// 剩余需要移动数据为零
else
{
bMoveRet = TRUE;
break;
}
// 首先定位当前读取指针
zfseek ( zfp, nCurrReadOffset, ZSEEK_SET );
// 读取一块准备移动的数据
memset ( szBlockReadBuff, 0, RECCNT_PERBLK * m_nRecLen );
nRead = zfread ( szBlockReadBuff, sizeof(char), nBlockToReadBytes, zfp );
if(nRead != nBlockToReadBytes)
{
bMoveRet = FALSE;
break;
}
// 定位准备写入数据的位置(当前位置-(0-nMoveOffset)-nBlockToReadBytes, nMoveOffset<0)
zfseek (zfp, 0-nBlockToReadBytes, ZSEEK_CUR);
zfseek (zfp, 0-(0-nMoveOffset), ZSEEK_CUR);
// 在新位置写入已读取数据
nWritten = zfwrite ( szBlockReadBuff, sizeof(char), nBlockToReadBytes, zfp);
if ( nWritten != nBlockToReadBytes )
{
bMoveRet = FALSE;
break;
}
// 文件指针加本次长度,为下次定位准备
nCurrReadOffset += nBlockToReadBytes;
}
}
// 若位移为正(后移数据)从文件尾部开始搬运文件
// * * * | * * *
// 1 2 3 4 5 6
// ====> ====>
else
{
while (1)
{
// 剩余需要移动的数据大于一块长度
if ( nFileBytesToMove >= (long)(RECCNT_PERBLK * m_nRecLen) )
{
nBlockToReadBytes = RECCNT_PERBLK * m_nRecLen;
nFileBytesToMove -= RECCNT_PERBLK * m_nRecLen;
}
// 剩余需要移动的数据小于一块但大于零
else if ( nFileBytesToMove > 0 )
{
nBlockToReadBytes = nFileBytesToMove;
nFileBytesToMove = 0;
}
else
{
bMoveRet = TRUE;
break;
}
// 首先定位当前读取数据文件指针位移
zfseek ( zfp, nMoveBeginOffset+nFileBytesToMove, ZSEEK_SET );
// 读取一块准备移动的数据
memset ( szBlockReadBuff, 0, RECCNT_PERBLK*m_nRecLen );
nRead = zfread ( szBlockReadBuff, sizeof(char), nBlockToReadBytes, zfp );
if(nRead != nBlockToReadBytes)
{
bMoveRet = FALSE;
break;
}
// 定位准备写入数据的位置(当前位置-nBlockToReadBytes+nMoveOffset)
zfseek (zfp, 0-nBlockToReadBytes, ZSEEK_CUR);
zfseek (zfp, nMoveOffset, ZSEEK_CUR);
// 在新位置写入数据
nWritten = zfwrite ( szBlockReadBuff, sizeof(char), nBlockToReadBytes, zfp);
if ( nWritten != nBlockToReadBytes )
{
bMoveRet = FALSE;
break;
}
}// end of while 1
}// end of else if ( nMoveOffset > 0 )
/***
* 若文件后移,以空格补入移动位置的数据; 若文件前移,以 '\0' 补入文件尾部
***/
/*_ENDMOVE_:*/
if ( nMoveOffset > 0 )
{
zfseek (zfp, nMoveBeginOffset, ZSEEK_SET);
memset ( szBlockReadBuff, 0x20, RECCNT_PERBLK*m_nRecLen );
nWritten = zfwrite ( szBlockReadBuff, sizeof(char), nMoveOffset, zfp);
if ( nWritten != (int)nMoveOffset)
bMoveRet = FALSE;
else
bMoveRet = TRUE;
}
else
{
zfseek (zfp, 0 - (0-nMoveOffset), ZSEEK_END );
memset ( szBlockReadBuff, 0x00, RECCNT_PERBLK*m_nRecLen );
nWritten = zfwrite ( szBlockReadBuff, sizeof(char), 0-nMoveOffset, zfp );
if ( nWritten != (int)(0-nMoveOffset) )
bMoveRet = FALSE;
else
bMoveRet = TRUE;
// 2002/11/20 添加,截断删除数据
zfseek (zfp, 0 - (0-nMoveOffset), ZSEEK_END );
ztruncate ( zfp->fn );
// 2002/11/20 添加,截断删除数据
}
/***
* 释放缓存,返回结果
***/
free(szBlockReadBuff);
szBlockReadBuff=NULL;
return bMoveRet;
}
////////////////////////////////////////////////////////////////////////////////////////
// 功能说明 : 快速排序
// 输入参数 :
// 输出参数 : VOID
// 返回值 : BOOL
////////////////////////////////////////////////////////////////////////////////////////
BOOL CSortRecordFile::QuickSort (
IN unsigned int nCompFieldOffset, /* 排序字段在记录中位移 */
IN unsigned int nCompFieldLength, /* 排序字段在记录中长度 */
IN unsigned int nStartRecordNO, /* 本次排序起始记录号 */
IN unsigned int nEndRecordNO /* 本次排序终止记录号 */
)
{
BOOL bRet = TRUE;
int nPivotIndex = 0;
int nPartitionPos = 0;
if ( nCompFieldOffset+nCompFieldLength > m_nRecLen )
return FALSE;
if ( nStartRecordNO > nEndRecordNO )
return FALSE;
nPivotIndex = _qsort_findpivot ( nStartRecordNO, nEndRecordNO);
bRet = _qsort_swap ( nPivotIndex, nEndRecordNO );
nPartitionPos = _qsort_partition (
nCompFieldOffset, nCompFieldLength,
(int)nStartRecordNO-1, nEndRecordNO, nEndRecordNO
);
_qsort_swap ( nPartitionPos, nEndRecordNO );
if ( (nPartitionPos-(int)nStartRecordNO) > 1 )
QuickSort (
nCompFieldOffset, nCompFieldLength,
nStartRecordNO, nPartitionPos-1 );
if ( ((int)nEndRecordNO-nPartitionPos) > 1 )
QuickSort (
nCompFieldOffset, nCompFieldLength,
nPartitionPos+1, nEndRecordNO );
return bRet;
}
////////////////////////////////////////////////////////////////////////////////////////
// 功能说明 :
// 输入参数 :
// 输出参数 : VOID
// 返回值 : int
////////////////////////////////////////////////////////////////////////////////////////
int CSortRecordFile::_qsort_findpivot ( IN unsigned int nStartRecordNO, IN unsigned int nEndRecordNO )
{
return (( nStartRecordNO + nEndRecordNO ) /2 ) ;
}
////////////////////////////////////////////////////////////////////////////////////////
// 功能说明 : 对参加快速排序的文件记录进行交换
// 输入参数 :
// 输出参数 : VOID
// 返回值 : BOOL
////////////////////////////////////////////////////////////////////////////////////////
BOOL CSortRecordFile::_qsort_swap (
IN unsigned int nStartRecordNO,
IN unsigned int nEndRecordNO
)
{
BOOL bRet = TRUE;
char *szStartBuff = NULL;
char *szEndBuff = NULL;
int nBytes = 0;
// 文件未打开,返回失败
if ( zfp == NULL )
{
bRet = FALSE;
goto __ENDSWAP__;
}
// 申请交换临时空间
szStartBuff = (char*) malloc (sizeof(char)*m_nRecLen + 1);
if (szStartBuff == NULL)
{
printf ( "_qsort_swap malloc %d bytes memory fail\n", m_nRecLen );
goto __ENDSWAP__;
}
memset ( szStartBuff, 0, m_nRecLen+1 );
szEndBuff = (char*) malloc (sizeof(char)*m_nRecLen + 1);
if (szEndBuff == NULL)
{
printf ( "_qsort_swap malloc %d bytes memory fail\n", m_nRecLen );
goto __ENDSWAP__;
}
memset ( szEndBuff, 0, m_nRecLen+1 );
// 读取准备交换的数据
bRet = ReadRecord ( nStartRecordNO*m_nRecLen, szStartBuff, m_nRecLen, &nBytes );
if ( bRet != TRUE || nBytes != (int)m_nRecLen )
{
bRet = FALSE;
goto __ENDSWAP__;
}
bRet = ReadRecord ( nEndRecordNO*m_nRecLen, szEndBuff, m_nRecLen, &nBytes );
if ( bRet != TRUE || nBytes != (int)m_nRecLen )
{
bRet = FALSE;
goto __ENDSWAP__;
}
// 写入交换数据 szStartBuff ==> nEndRecordNO
bRet = WriteRecord ( nEndRecordNO*m_nRecLen, szStartBuff, m_nRecLen, &nBytes );
if ( bRet != TRUE || nBytes != (int)m_nRecLen )
{
bRet = FALSE;
goto __ENDSWAP__;
}
// 写入交换数据 szEndBuff ==> nStartRecordNO
bRet = WriteRecord ( nStartRecordNO*m_nRecLen, szEndBuff, m_nRecLen, &nBytes );
if ( bRet != TRUE || nBytes != (int)m_nRecLen )
{
bRet = FALSE;
goto __ENDSWAP__;
}
__ENDSWAP__:
MFree(szStartBuff);
MFree(szEndBuff);
return bRet;
}
////////////////////////////////////////////////////////////////////////////////////////
// 功能说明 : 获取快速排序某记录键值
// 输入参数 :
// 输出参数 : pKeyBuff 获取键值
// 返回值 : BOOL
////////////////////////////////////////////////////////////////////////////////////////
BOOL CSortRecordFile::_qsort_getkey(
IN unsigned int nCompFieldOffset, /* 键值字段在记录中位移 */
IN unsigned int nCompFieldLength, /* 键值字段在记录中长度 */
IN unsigned int nRecordNO, /* 欲获取键值的记录号 */
OUT void *pKeyBuff /* 获取的键值缓冲 */
)
{
BOOL bRet = TRUE;
char *szKeyBuff = NULL;
int nBytes = 0;
// 文件未打开或无出缓冲,返回失败
if ( zfp == NULL || pKeyBuff == NULL )
{
bRet = FALSE;
goto __ENDGETKEY__;
}
// 申请交换临时空间
szKeyBuff = (char*) malloc (sizeof(char)*m_nRecLen + 1);
if (szKeyBuff == NULL)
{
printf ( "_qsort_swap malloc %d bytes memory fail\n", m_nRecLen );
goto __ENDGETKEY__;
}
memset ( szKeyBuff, 0, m_nRecLen+1 );
// 读取比较用的键值
bRet = ReadRecord ( nRecordNO*m_nRecLen, szKeyBuff, m_nRecLen, &nBytes );
if ( bRet != TRUE || nBytes != (int)m_nRecLen )
{
bRet = FALSE;
MFree(szKeyBuff);
goto __ENDGETKEY__;
}
// 复制读取到的键值
memset ( pKeyBuff, 0, nCompFieldLength );
memcpy ( pKeyBuff, szKeyBuff+nCompFieldOffset, nCompFieldLength );
__ENDGETKEY__:
MFree(szKeyBuff);
return bRet;
}
////////////////////////////////////////////////////////////////////////////////////////
// 功能说明 : 找出快速排序本次的分界点
// 输入参数 :
// 输出参数 : VOID
// 返回值 : int 本次分界点
////////////////////////////////////////////////////////////////////////////////////////
int CSortRecordFile::_qsort_partition (
IN unsigned int nCompFieldOffset, /* 比较字段在记录中位移 */
IN unsigned int nCompFieldLength, /* 比较字段长度 */
IN unsigned int nStartRecordNO, /* 比较的起始记录号 */
IN unsigned int nEndRecordNO, /* 比较的终止记录号 */
IN unsigned int nPivotRecordNO /* 比较的分界记录号 */
)
{
char *pKeyBuff = NULL;
char *pPivBuff = NULL;
pKeyBuff = (char*) malloc ( sizeof(char) * m_nRecLen + 1 );
pPivBuff = (char*) malloc ( sizeof(char) * m_nRecLen + 1 );
if ( pKeyBuff == NULL || pPivBuff == NULL )
{
nStartRecordNO = -1;
goto __ENDPARTITION__;
}
_qsort_getkey (nCompFieldOffset, nCompFieldLength, nPivotRecordNO, pPivBuff );
do
{
while (1)
{
++nStartRecordNO;
if(nStartRecordNO>=nPivotRecordNO) /* nPivotRecordNO 不用参加比较 */
break;
_qsort_getkey (nCompFieldOffset, nCompFieldLength, nStartRecordNO, pKeyBuff );
if ( memcmp ( pKeyBuff, pPivBuff, nCompFieldLength ) > 0 )
break;
}
while(1)
{
if(nEndRecordNO==0) /* 记录数为零不用比较 */
break;
--nEndRecordNO;
_qsort_getkey (nCompFieldOffset, nCompFieldLength, nEndRecordNO, pKeyBuff );
if ( memcmp ( pKeyBuff, pPivBuff, nCompFieldLength ) < 0 )
break;
}
_qsort_swap ( nStartRecordNO, nEndRecordNO );
}while ( nStartRecordNO < nEndRecordNO );
_qsort_swap ( nStartRecordNO, nEndRecordNO );
__ENDPARTITION__:
MFree(pPivBuff);
MFree(pKeyBuff);
return nStartRecordNO;
}
////////////////////////////////////////////////////////////////////////////////////////
// [11/4/2002] end line of sortfile.cpp
////////////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -