?? usortfile.cpp
字號:
{
if ( (long)(nMoveBeginOffset - (0-nMoveOffset)) < 0 ) // 前移位置超出文件首部
{
free(szBlockReadBuff);
return FALSE;
}
// 初始化變量,文件指針位置
nCurrReadOffset = nMoveBeginOffset;
// 開始移動
while (1)
{
// 剩余需要移動的數(shù)據(jù)大于一塊長度
if ( nFileBytesToMove >= (long)(RECCNT_PERBLK * m_nRecLen) )
{
nBlockToReadBytes = RECCNT_PERBLK * m_nRecLen;
nFileBytesToMove -= RECCNT_PERBLK * m_nRecLen;
}
// 剩余需要移動的數(shù)據(jù)小于一塊但大于零
else if ( nFileBytesToMove > 0 )
{
nBlockToReadBytes = nFileBytesToMove;
nFileBytesToMove = 0; // 準(zhǔn)備退出條件
}
// 剩余需要移動數(shù)據(jù)為零
else
{
bMoveRet = TRUE;
break;
}
// 首先定位當(dāng)前讀取指針
zfseek ( zfp, nCurrReadOffset, ZSEEK_SET );
// 讀取一塊準(zhǔn)備移動的數(shù)據(jù)
memset ( szBlockReadBuff, 0, RECCNT_PERBLK * m_nRecLen );
nRead = zfread ( szBlockReadBuff, sizeof(char), nBlockToReadBytes, zfp );
if(nRead != nBlockToReadBytes)
{
bMoveRet = FALSE;
break;
}
// 定位準(zhǔn)備寫入數(shù)據(jù)的位置(當(dāng)前位置-(0-nMoveOffset)-nBlockToReadBytes, nMoveOffset<0)
zfseek (zfp, 0-nBlockToReadBytes, ZSEEK_CUR);
zfseek (zfp, 0-(0-nMoveOffset), ZSEEK_CUR);
// 在新位置寫入已讀取數(shù)據(jù)
nWritten = zfwrite ( szBlockReadBuff, sizeof(char), nBlockToReadBytes, zfp);
if ( nWritten != nBlockToReadBytes )
{
bMoveRet = FALSE;
break;
}
// 文件指針加本次長度,為下次定位準(zhǔn)備
nCurrReadOffset += nBlockToReadBytes;
}
}
// 若位移為正(后移數(shù)據(jù))從文件尾部開始搬運(yùn)文件
// * * * | * * *
// 1 2 3 4 5 6
// ====> ====>
else
{
while (1)
{
// 剩余需要移動的數(shù)據(jù)大于一塊長度
if ( nFileBytesToMove >= (long)(RECCNT_PERBLK * m_nRecLen) )
{
nBlockToReadBytes = RECCNT_PERBLK * m_nRecLen;
nFileBytesToMove -= RECCNT_PERBLK * m_nRecLen;
}
// 剩余需要移動的數(shù)據(jù)小于一塊但大于零
else if ( nFileBytesToMove > 0 )
{
nBlockToReadBytes = nFileBytesToMove;
nFileBytesToMove = 0;
}
else
{
bMoveRet = TRUE;
break;
}
// 首先定位當(dāng)前讀取數(shù)據(jù)文件指針位移
zfseek ( zfp, nMoveBeginOffset+nFileBytesToMove, ZSEEK_SET );
// 讀取一塊準(zhǔn)備移動的數(shù)據(jù)
memset ( szBlockReadBuff, 0, RECCNT_PERBLK*m_nRecLen );
nRead = zfread ( szBlockReadBuff, sizeof(char), nBlockToReadBytes, zfp );
if(nRead != nBlockToReadBytes)
{
bMoveRet = FALSE;
break;
}
// 定位準(zhǔn)備寫入數(shù)據(jù)的位置(當(dāng)前位置-nBlockToReadBytes+nMoveOffset)
zfseek (zfp, 0-nBlockToReadBytes, ZSEEK_CUR);
zfseek (zfp, nMoveOffset, ZSEEK_CUR);
// 在新位置寫入數(shù)據(jù)
nWritten = zfwrite ( szBlockReadBuff, sizeof(char), nBlockToReadBytes, zfp);
if ( nWritten != nBlockToReadBytes )
{
bMoveRet = FALSE;
break;
}
}// end of while 1
}// end of else if ( nMoveOffset > 0 )
/***
* 若文件后移,以空格補(bǔ)入移動位置的數(shù)據(jù); 若文件前移,以 '\0' 補(bǔ)入文件尾部
***/
/*_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 添加,截?cái)鄤h除數(shù)據(jù)
zfseek (zfp, 0 - (0-nMoveOffset), ZSEEK_END );
ztruncate ( zfp->fn );
// 2002/11/20 添加,截?cái)鄤h除數(shù)據(jù)
}
/***
* 釋放緩存,返回結(jié)果
***/
free(szBlockReadBuff);
szBlockReadBuff=NULL;
return bMoveRet;
}
////////////////////////////////////////////////////////////////////////////////////////
// 功能說明 : 快速排序
// 輸入?yún)?shù) :
// 輸出參數(shù) : 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;
}
////////////////////////////////////////////////////////////////////////////////////////
// 功能說明 :
// 輸入?yún)?shù) :
// 輸出參數(shù) : VOID
// 返回值 : int
////////////////////////////////////////////////////////////////////////////////////////
int CSortRecordFile::_qsort_findpivot ( IN unsigned int nStartRecordNO, IN unsigned int nEndRecordNO )
{
return (( nStartRecordNO + nEndRecordNO ) /2 ) ;
}
////////////////////////////////////////////////////////////////////////////////////////
// 功能說明 : 對參加快速排序的文件記錄進(jìn)行交換
// 輸入?yún)?shù) :
// 輸出參數(shù) : 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__;
}
// 申請交換臨時(shí)空間
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 );
// 讀取準(zhǔn)備交換的數(shù)據(jù)
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__;
}
// 寫入交換數(shù)據(jù) szStartBuff ==> nEndRecordNO
bRet = WriteRecord ( nEndRecordNO*m_nRecLen, szStartBuff, m_nRecLen, &nBytes );
if ( bRet != TRUE || nBytes != (int)m_nRecLen )
{
bRet = FALSE;
goto __ENDSWAP__;
}
// 寫入交換數(shù)據(jù) 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;
}
////////////////////////////////////////////////////////////////////////////////////////
// 功能說明 : 獲取快速排序某記錄鍵值
// 輸入?yún)?shù) :
// 輸出參數(shù) : 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__;
}
// 申請交換臨時(shí)空間
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__;
}
// 復(fù)制讀取到的鍵值
memset ( pKeyBuff, 0, nCompFieldLength );
memcpy ( pKeyBuff, szKeyBuff+nCompFieldOffset, nCompFieldLength );
__ENDGETKEY__:
MFree(szKeyBuff);
return bRet;
}
////////////////////////////////////////////////////////////////////////////////////////
// 功能說明 : 找出快速排序本次的分界點(diǎn)
// 輸入?yún)?shù) :
// 輸出參數(shù) : VOID
// 返回值 : int 本次分界點(diǎn)
////////////////////////////////////////////////////////////////////////////////////////
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) /* 記錄數(shù)為零不用比較 */
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
////////////////////////////////////////////////////////////////////////////////////////
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -