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

📄 cdbf.cpp

📁 dbf文件的读写类。它直接对dbf文件进行文件级的操作
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// DBF.cpp: implementation of the CFDBF class.
//
//////////////////////////////////////////////////////////////////////
#include "CDBF.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CFDBF::CFDBF()
{
	m_nCurrOffset    = 0;
	m_nRecBeginOffset= 0;
	m_nStructSize    = 0;
	m_nCurrRecNo     = 0;
	_open            = false;
	recInfo.rec_num  = 0;
	recInfo.rec_size = 0;
	recInfo.fld_num  = 0;
	_open            = false;
    m_CurrLockType   = _AutoLock;
    m_FieldNum       = 0;
}

CFDBF::~CFDBF()
{
    ClearFieldInfo();
    Close();
}

int CFDBF::Space(char *p)
{
	char *s = p;
	while (*s) {
		if(*s == ' ')
            s++;
		else
            return 0;
	}
	return 1;
}

void CFDBF::Ltrim(char *s)
{
	int i=0;
	int len;
	char *tmp;
	len=strlen(s);
	if(Space(s)){
		*s='\0';
		return;
	}
	tmp=s;
	for(i=0; *tmp && *tmp==' '; tmp++,i++);
	memmove(s,tmp,len);
}

void CFDBF::Rtrim(char *s)
{
	int len;
	len=strlen(s);
	char *p=s+len-1;

	if (Space(s)){
		*s='\0';
		return;
	 }
	while(*p==' ') p--;
	*(++p)='\0';
}

void CFDBF::Alltrim(char *s)
{
	if (s==NULL) return;
	Ltrim(s);
	Rtrim(s);
}


int CFDBF::Open(const char *filename, int opentype, int lockType)
{
	unsigned char tmpstr[33];
	int i,offset;
	long tmpoffset;

	if (_open)
	{
		strcpy(errMessage,"opened.");
		return DBF_FAIL;
	}

    m_CurrLockType = lockType;

	m_nCurrOffset=0;
	m_nRecBeginOffset=0;
	m_nStructSize=0;
	m_nCurrRecNo=0;
	_open=false;
	recInfo.rec_num=0;
	recInfo.rec_size=0;
	recInfo.fld_num=0;

	if (opentype == O_RDONLY)
		_dbfhandle = _sopen(filename, O_RDONLY | O_BINARY, SH_DENYNO, S_IREAD );
	else
		_dbfhandle = _sopen(filename, O_RDWR | O_BINARY, SH_DENYNO, S_IREAD | S_IWRITE );
	if (_dbfhandle==-1)
	{
		strcpy(errMessage,"open dbf failed.");
		return DBF_FAIL;
	}

    if (m_CurrLockType == _AutoLock)
    {
        LockHead();
    }
	//取记录数
    memset(tmpstr, 0, sizeof(tmpstr));
	lseek(_dbfhandle,4L,SEEK_SET);
	read(_dbfhandle,tmpstr,4L);
    recInfo.rec_num = *(unsigned long *)&tmpstr;

	//取记录长度
    memset(tmpstr, 0, sizeof(tmpstr));
	lseek(_dbfhandle, 10L, SEEK_SET);
	read(_dbfhandle, tmpstr, 2L);
    recInfo.rec_size = *(unsigned short *)&tmpstr;

	//取文件结构长度
    memset(tmpstr, 0, sizeof(tmpstr));
	lseek(_dbfhandle, 8L, SEEK_SET);
	read(_dbfhandle, tmpstr, 2L);
    m_nStructSize = *(unsigned short *)&tmpstr;

	//取字段信息
	i        = 0;
	offset   = 0;
	tmpoffset= 32;
	while(i < MAX_FLD_NUM)
	{
		lseek(_dbfhandle,tmpoffset,SEEK_SET);
		//取字段名
		read(_dbfhandle,tmpstr,32);
		recInfo.fld_num++;
		memcpy(fld_info[i].name,tmpstr,10);
		fld_info[i].name[10]=0;
        Alltrim(fld_info[i].name);

		//取字段类型
		fld_info[i].type=tmpstr[11];

		//取字段长度
		fld_info[i].width=tmpstr[16];

		//取字段偏移量
		fld_info[i].offset=offset;

		//取小数位数
		fld_info[i].dec_d=tmpstr[17];

		offset+=fld_info[i].width;
		tmpoffset+=32;
		if (tmpoffset >= (long)m_nStructSize - 1)
			break;
		i++;
	}

    if (m_CurrLockType == _AutoLock)
    {
        UnlockHead();
    }

	m_nRecBeginOffset = m_nStructSize;

	m_nCurrOffset = m_nRecBeginOffset;

	_open = true;

    strcpy(m_FileName, filename);

	return DBF_SUCCESS;
}

void CFDBF::Close()
{
	if (_open)
		close(_dbfhandle);

	m_nCurrOffset     = 0;
	m_nRecBeginOffset = 0;
	m_nStructSize     = 0;
	m_nCurrRecNo      = 0;
	_open             = false;
	recInfo.rec_num   = 0;
	recInfo.rec_size  = 0;
	recInfo.fld_num   = 0;
	_open             = false;
}

int CFDBF::LockRecord()
{
    long offset;
    time_t t1, t2;
    int RetCode;

    time(&t1);
    
    offset = BASE_LOCK_OFFSET + m_nCurrOffset;//锁定当前

    do  {
        RetCode = lock( _dbfhandle, offset, recInfo.rec_size);
        time(&t2);
    }while(difftime(t2, t1) <= 5 && RetCode != 0);

	return DBF_SUCCESS;
}

int CFDBF::UnlockRecord()
{
    long offset;
    int RetCode = 0;

    offset = BASE_LOCK_OFFSET + m_nCurrOffset;//解锁当前

    RetCode =unlock(_dbfhandle, offset, recInfo.rec_size);
    if(RetCode == 0)
     return DBF_SUCCESS;
    else
        return DBF_FAIL;

}

int CFDBF::LockHead()
{
    long offset;

    offset = BASE_LOCK_OFFSET + 1L;

	if (lock(_dbfhandle, offset, 32L)==-1)
	{
		strcpy(errMessage,"locking failed.");
		return DBF_FAIL;
	}
	return DBF_SUCCESS;
}

int CFDBF::UnlockHead()
{
    long offset;

    offset = BASE_LOCK_OFFSET + 1L;

	if (unlock(_dbfhandle, offset, 32L)==-1)
	{
		strcpy(errMessage,"Unlocking failed.");
		return DBF_FAIL;
	}
	return DBF_SUCCESS;
}

int CFDBF::GoTo(long recNo)
{
	m_nCurrOffset = m_nRecBeginOffset + (recNo-1) * recInfo.rec_size;
	if (IsEof() || IsBof())
	{
		strcpy(errMessage,"is eof or bof.");
		return DBF_FAIL;
	}
	m_nCurrRecNo=recNo;
	return DBF_SUCCESS;
}

//功能:读取指定记录序号的内容到内部缓冲区
//返回值:成功:DBF_SUCCESS,失败:DBF_FAIL;
int CFDBF::ReadRecord(long recNo)
{
	char tmpstr[MAX_RECORD_SIZE+1];
	int nRc;
	tmpstr[0]=0;

    if ( recNo < 1L || recNo > GetRecordNum() )
    {
        return DBF_FAIL;
    }

	if ( (nRc = GoTo(recNo)) == DBF_FAIL )
    {
		return nRc;
    }

    if ( m_CurrLockType == _AutoLock )
    {
        if ((nRc = LockRecord()) == DBF_FAIL)
        {
            return nRc;
        }
    }

    lseek( _dbfhandle, m_nCurrOffset, SEEK_SET );
	if ( read(_dbfhandle, tmpstr, recInfo.rec_size) != recInfo.rec_size )
    {
        nRc = DBF_FAIL;
    }

    if ( m_CurrLockType == _AutoLock )
    {
        if ( (nRc = UnlockRecord()) == DBF_FAIL )
        {
            return nRc;
        }
    }

	m_nCurrRecNo = recNo;
	memcpy(recInfo.rec_data, tmpstr, recInfo.rec_size);
	return DBF_SUCCESS;
}

//功能:读取当前记录的内容到内部缓冲区
int CFDBF::ReadRecord(void)
{
    if (IsBof() || IsEof())
    {
        strcpy(errMessage,"Is Bof or Eof!");
        return DBF_FAIL;
    }

    return ReadRecord(m_nCurrRecNo);
}

//功能:判断此记录是否已经被打上删除标记
//注意:此函数必须在读取了一条记录内容后才能使用
bool CFDBF::IsDelete()
{
    if (recInfo.rec_data[0] == RECORD_DEL_FLAG)
        return true;
    return false;
}

//功能:根据字段名查找字段
//返回值:成功-字段序号; 失败--1
int CFDBF::FindFld(const char *fldName)
{
	int i;
	for(i=0; i<recInfo.fld_num; i++)
	{
		if ( stricmp(fld_info[i].name,fldName) == 0 )
		{
			return i;
		}
	}
	return -1;
}

int CFDBF::GetFldValue(const char *fldName,char *fldValue)
{
	long i;

	i = FindFld(fldName);
	if (i < 0)
		return DBF_FAIL;

	memcpy(fldValue,recInfo.rec_data+fld_info[i].offset+1,fld_info[i].width);
	fldValue[fld_info[i].width]='\0';
        Alltrim(fldValue);
	return DBF_SUCCESS;
}

int CFDBF::GetFldValue(const char *fldName, char &fldValue)
{
	long i;

	i = FindFld(fldName);
	if (i < 0)
		return DBF_FAIL;

	fldValue = recInfo.rec_data[fld_info[i].offset+1];
	return DBF_SUCCESS;
}

int CFDBF::GetFldValue(const char *fldName,double &fldValue)
{
	long i;
	char tmpstr[30];

	i = FindFld(fldName);
	if (i < 0)
		return DBF_FAIL;
	memcpy(tmpstr,recInfo.rec_data+fld_info[i].offset+1,fld_info[i].width);
	tmpstr[fld_info[i].width]='\0';
    Alltrim(tmpstr);
    if (memcmp(tmpstr, "-.", 2) == 0)
        strcpy(tmpstr, "0");
	fldValue = atof(tmpstr);
	return DBF_SUCCESS;
}

int CFDBF::GetFldValue(const char *fldName,int &fldValue)
{
	long i;
	char tmpstr[30];

	i = FindFld(fldName);
	if (i < 0)
		return DBF_FAIL;
	memcpy(tmpstr,recInfo.rec_data+fld_info[i].offset+1,fld_info[i].width);
	tmpstr[fld_info[i].width]='\0';
    Alltrim(tmpstr);
    if (stricmp(tmpstr, "-") == 0)
        strcpy(tmpstr, "0");
	fldValue = atoi(tmpstr);
	return DBF_SUCCESS;
}

int CFDBF::GetFldValue(const char *fldName,long &fldValue)
{
	long i;
	char tmpstr[30];

	i = FindFld(fldName);
	if (i < 0)
		return DBF_FAIL;
	memcpy(tmpstr,recInfo.rec_data+fld_info[i].offset+1,fld_info[i].width);
	tmpstr[fld_info[i].width]='\0';
    Alltrim(tmpstr);
    if (stricmp(tmpstr, "-") == 0)
        strcpy(tmpstr, "0");
	fldValue = atol(tmpstr);
	return DBF_SUCCESS;
}

//功能:判断记录指针是否在最后一条记录之后
bool CFDBF::IsEof()
{
	if (m_nCurrOffset >= (m_nRecBeginOffset + recInfo.rec_num * recInfo.rec_size) )
	{
		return true;
	}
    
	return false;

}

//功能:判断是否记录指针在第一条记录之前
bool CFDBF::IsBof()
{
	if (m_nCurrOffset < m_nRecBeginOffset)
	{
		return true;
	}
    
	return false;
}

int CFDBF::ModifyFileDate()
{
    int nRc;
    time_t t;
    struct tm tmlocal;

    t = ::time(&t);
    tmlocal = *(::localtime(&t));

    f_date[0] = (unsigned char)(tmlocal.tm_year % 100);
    f_date[1] = (unsigned char)(tmlocal.tm_mon + 1);
    f_date[2] = (unsigned char)tmlocal.tm_mday;

    lseek(_dbfhandle, 1L, SEEK_SET);

    if (m_HeadLockType == 'H')
    {
        if ((nRc = LockHead())==DBF_FAIL)
        {
            return nRc;
        }
    }
	write(_dbfhandle, f_date, 3);

    if (m_HeadLockType == 'H')
    {
        if ((nRc = UnlockHead())==DBF_FAIL)
        {
            return nRc;
        }
    }
	return DBF_SUCCESS;
}

int CFDBF::GetRecordNum()
{
	char tmpstr[10];
	//取记录数
    if (m_CurrLockType == _AutoLock)
    {
    	LockHead();
    }

    memset(tmpstr, 0, sizeof(tmpstr));
	lseek(_dbfhandle,4L,SEEK_SET);
	read(_dbfhandle,tmpstr,4L);
    recInfo.rec_num = *(unsigned long *)&tmpstr;

    if (m_CurrLockType == _AutoLock)
    {
        UnlockHead();
    }
    
	return recInfo.rec_num;
}

/*int CFDBF::EditBegin()
{
	int nRc;
	if (!_open)
	{
		strcpy(errMessage,"not open");
		return DBF_FAIL;
	}
	nRc=LockRecord();
	if (nRc==DBF_FAIL)
		return nRc;
	return DBF_FAIL;
}

int CFDBF::EditEnd()
{
	int nRc;
	if (!_open)
	{
		strcpy(errMessage,"not open");
		return DBF_FAIL;
	}
	nRc=UnlockRecord();
	if (nRc==DBF_FAIL)
		return nRc;
	return DBF_FAIL;
}
*/

long CFDBF::AddNewEmptyRecord()
{

    memset(recInfo.rec_data, ' ', sizeof(recInfo.rec_data));   //置空
    return recInfo.rec_num++;

}

int CFDBF::UpdateNewRecord()
{
  //在AddNewEmptyRecord,FillFldValue 填写recInfo.rec_data值之后调用

    int nRc;
    unsigned long tmp_rec_num=0;
    char tmpchr[2];
    /////////////////////
    if (LockFile() == DBF_FAIL)
        return ((int)DBF_FAIL);

     GetRecordNum();

     m_nCurrOffset = m_nRecBeginOffset + recInfo.rec_num * recInfo.rec_size;
     lseek(_dbfhandle, m_nCurrOffset + recInfo.rec_size, SEEK_SET); //偏移到文件未

     nRc = write(_dbfhandle, recInfo.rec_data, recInfo.rec_size);//写纪录
    if (nRc != recInfo.rec_size)
    {
        UnlockFile();
        return ((int)DBF_FAIL);
    }

    tmp_rec_num = recInfo.rec_num + 1L;

	//写记录数
    lseek(_dbfhandle, 4L, SEEK_SET);
    nRc = write(_dbfhandle, &tmp_rec_num, 4);
    recInfo.rec_num++; //纪录数增加
     ////////////


    lseek(_dbfhandle, m_nCurrOffset + recInfo.rec_size, SEEK_SET);	//写文件结束符

    tmpchr[0] = FILE_EOF_FLAG;
    nRc = write(_dbfhandle, tmpchr, 1);

    m_HeadLockType = 'F';
    ModifyFileDate();

    if (UnlockFile() == DBF_FAIL)
        return ((int)DBF_FAIL);

      return DBF_SUCCESS;
}

int CFDBF::FillFldValue(const char *fldName, const char *fldValue)
{
	char fmt[30], tmpstr[MAX_FLD_DATALEN];
	long i;

	i = FindFld(fldName);
	if (i < 0)
		return DBF_FAIL;

	sprintf(fmt,"%%-%ds",fld_info[i].width);
	sprintf(tmpstr,fmt,fldValue);
	memcpy(recInfo.rec_data+1+fld_info[i].offset, tmpstr, fld_info[i].width);

	return DBF_SUCCESS;
}

int CFDBF::FillFldValue(const char *fldName, int fldValue)
{
	char fmt[30], tmpstr[MAX_FLD_DATALEN];
	long i;

	i = FindFld(fldName);
	if (i < 0)
		return DBF_FAIL;

	sprintf(fmt,"%%%dd",fld_info[i].width);
	sprintf(tmpstr,fmt,fldValue);
	memcpy(recInfo.rec_data+1+fld_info[i].offset, tmpstr, fld_info[i].width);
	return DBF_SUCCESS;
}

int CFDBF::FillFldValue(const char *fldName, char fldValue)
{
	long i;

	i = FindFld(fldName);
	if (i < 0)

⌨️ 快捷键说明

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