最近在分析离线数据使用时的bug,发现代码中对std::ifstream成员函数使用存在疑问,所以就写了个简单测试程序来分析std::ifstream成员函数对应那些系统调用。
目录
1.gcount
2.seekg和tellg
3.read
代码如下:
test.cpp
#include <iostream>
#include <fstream>
#include <atomic>
#include <string>
using namespace std;
/*
1.fseek函数:C语言标准库函数
作用:设置文件读写位置
函数原型:int fseek(FILE *fp, LONG offset, int origin);
参数含义:
fp 文件指针
offset 相对于origin规定的偏移位置量
origin 指针移动的起始位置,取值如下:
SEEK_SET 文件开始位置
SEEK_CUR 文件当前位置
SEEK_END 文件结束位置
返回值:
成功,返回0,失败返回非0值,并设置error的值,可以用perror()函数输出错误。
2.ftell函数:C语言标准库函数
作用:用于得到文件位置指针当前位置相对于文件首的偏移字节数
原型:
#include <stdio.h>
long ftell(FILE *stream);
获取文件大小:首先将文件的当前位置移到文件的末尾,然后调用函数ftell()获得当前位置相对于文件首的位移,该位移值等于文件所含字节数。
fseek(fp, 0L,SEEK_END);
len = ftell(fp);
3.lseek函数:linux下系统调用
lseek: 用于改变一个文件读写指针位置的一个系统调用。指针位置可以是绝对的或者相对的。
和fseek函数类似,但lseek返回的是一个off_t数值
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
offset为正则向文件末尾移动(向前移),为负数则向文件头部(向后移)。
返回值:
正确时返回文件读写指针距文件开头的字节大小,出错返回-1
lseek的作用是打开文件下一次读写的开始位置,因此还有以下两个作用
(1)拓展文件,不过一定要一次写的操作。迅雷等下载工具在下载文件时候先扩展一个空间然后再下载的。
int fd = open("test.txt",O_RDWR);
lseek(fd,0x1000, SEEK_SET);
write(fd, "a", 1);
close(fd);
(2)获取文件大小。
int fd = open("test.txt", O_RDWR);
printf("file size:%d \n", lseek(fd, 0, SEEK_END));
close(fd);
总结:lseek 功能包含 ftell + fseek
*/
/*
C++中seekp() seekg() tellp() tellg()
seekp:设置输出文件流的文件流指针位置
tellp::获取输出文件流的文件流指针位置
seekg:设置输入文件流的文件流指针位置
tellg:获取输入文件流的文件流指针位置
函数原型:
ostream& seekp( streampos pos );
ostream& seekp( streamoff off, ios::seek_dir dir );
istream& seekg( streampos pos );
istream& seekg( streamoff off, ios::seek_dir dir );
ostream& tellp()
istream& tellg()
参数含义:
pos:新的文件流指针位置值
off:需要偏移的值
dir:搜索的起始位置
dir参数用于对文件流指针的定位操作上,代表搜索的起始位置
在ios中定义的枚举类型:
enum seek_dir {beg, cur, end};
含义如下:
ios::beg:文件流的起始位置
ios::cur:文件流的当前位置
ios::end:文件流的结束位置
gcount(): 返回在对象上执行的最后一个未格式化的输入操作中提取的字符数,不涉及调用系统api
获取文件大小:
seekg(0, std::ios::end);
tellg();
*/
/*
iostream类评估流状态的4个功能函数:good(),bad(),fail(),和eof(),具体功能如下:
good():流没有遇到错误。
bad():数据流已遇到效应的流(即存储器分配失败,没有缓流等)。
fail():的完整性的错误:通常可恢复的错误(格式化/解析失败)。
eof():已达到文件结尾(EOF)字符。
*/
static std::atomic<int> count_num(0);
#define DB_IsBigEnd_FromRPHeaderAttr( HeaderAttr ) \
((bool) (HeaderAttr & 0X00000001))
//typedef unsigned int uint_t;
using uint_t = unsigned int;
typedef unsigned char Byte;
typedef unsigned short u_short;
#define DB_FORMAT_VER_MAX_LENGTH (16)
#define DB_DATA_VER_MAX_LENGTH (16)
#define DB_AUTHOR_MAX_LENGTH (8)
#define DB_DATE_MAX_LENGTH (8)
/* 小端到大端的变换宏 */
#define _V_GET_LITTLE_SHORT( x ) (short)( ( ( *((Byte*)x+1) ) << 8 ) | (*((Byte*)x)) )
#define _V_GET_LITTLE_LONG( x ) (int)( ( ( *((Byte*)x+3) ) << 24 ) | (( *((Byte*)x+2) ) << 16 ) \
| (( *((Byte*)x+1) ) << 8 ) | ( *((Byte*)x) ) )
#define _V_GET_LITTLE_FLOAT( x ) (*((float *)(x)))
#define _V_GET_BIGENDDIAN_SHORT( x ) (short)( ( ( *((Byte*)x) ) << 8 ) | (*((Byte*)x+1)) )
#define _V_GET_BIGENDDIAN_LONG( x ) (int)( ( ( *((Byte*)x) ) << 24 ) | (( *((Byte*)x+1) ) << 16 ) \
| (( *((Byte*)x+2) ) << 8 ) | ( *((Byte*)x+3) ) )
typedef struct _DB_Header_t
{
uint_t unAttr;
uint_t unHeaderSize;
uint_t unFrameSize;
char cFormatVer[DB_FORMAT_VER_MAX_LENGTH];
char cDataVer[DB_DATA_VER_MAX_LENGTH];
char cAuthor[DB_AUTHOR_MAX_LENGTH];
char cDate[DB_DATE_MAX_LENGTH];
uint_t unCalcRegionMaxSize;
uint_t unInfoRegionMaxSize;
uint_t unRPLinkShapePointMaxCnt;
uint_t unNameMaxLength;
uint_t unNameFrameOffset;
uint_t unDistrictFrameOffset;
uint_t unLevelCnt;
uint_t unLevelRecordSize;
uint_t pstLevelTable;
} DB_Header_t ;
typedef struct _DB_Level_t
{
u_int unAttr;
u_int unCalcRegionManagerHeaderOffset;
u_int unUnCompressedCalcRegionManagerHeaderOffset;
u_int unCalcRegionManagerHeaderSize;
u_int unInfoRegionManagerHeaderOffset;
u_int unInfoRegionManagerHeaderSize;
u_int unAdjacentNodeManagerHeaderOffset;
u_int unAdjacentNodeManagerHeaderSize;
} DB_Level_t;
typedef struct _DB_NameFrame_t
{
u_int unFrameSize;
u_int unStructSize;
u_int unNameIdxCnt;
u_int unNameIdxSize;
u_int punIdxTable;
u_int pusNameTable;
} DB_NameFrame_t;
typedef struct _DB_DistrictFrame_t
{
u_int unFrameSize;
u_int unStructSize;
u_int unDistrictCnt;
u_int unDistrictSize;
u_int pstDistrictTable;
} DB_DistrictFrame_t;
typedef struct _DB_AbsoluteNodeID_t
{
u_int unNodeID ;
u_int unNodeExtendID ;
} DB_AbsoluteNodeID_t;
typedef struct _DB_AbsoluteLinkID_t
{
u_int unLinkIDPart1;
u_int unLinkIDPart2;
u_int unLinkAttr;
} DB_AbsoluteLinkID_t;
typedef struct _DB_AdjacentNode_t
{
u_int nLongitude ;
u_int nLatitude ;
DB_AbsoluteNodeID_t stNodeID ;
DB_AbsoluteLinkID_t stLinkID ;
bool bIsStartNode ;
} DB_AdjacentNode_t ;
typedef struct _DB_AdjacentNodeMgr_t
{
u_int unSize ;
u_int unStructSize ;
u_int unCnt ;
u_int unRecordSize;
u_int pstAdjNodes;
} DB_AdjacentNodeMgr_t ;
typedef struct _DB_CalcRegion_ManagerHeader_t
{
u_int unFrameSize;
u_int unRankInfo;
u_int unRegionCnt;
u_int unRegionIdxSize;
u_int pstRegionIdxTable;
} DB_CalcRegion_ManagerHeader_t;
typedef struct _DB_DistrictRecord_t
{
u_short usCityNameIdx;
u_short usCountyNameIdx;
} DB_DistrictRecord_t;
typedef struct _DB_CalcRegion_Idx_t
{
u_short unRegionOffset;
u_short unUnCompressedRegionOffset ;
u_short unRegionSize;
u_short unCompressedRegionSize ;
} DB_CalcRegion_Idx_t;
//多个对象指向同一个文件操作
class DBFile
{
public:
DBFile(std::ifstream *DBFileHandle);
~DBFile();
int32_t seek_cur_to_end_size(std::ifstream *m_pDBFileHandle, int32_t start_seek_pos);
static int32_t seek_cur_to_end_size(std::ifstream& pFile, int32_t start_seek_pos);
private:
std::ifstream *m_pDBFileHandle;
};
DBFile::DBFile(std::ifstream *DBFileHandle)
{
if(DBFileHandle) {
count_num++;
m_pDBFileHandle = DBFileHandle;
}
}
DBFile::~DBFile()
{
if(m_pDBFileHandle) {
count_num--;
if(count_num <= 0) {
count_num = 0;
}
if (count_num <= 0 && m_pDBFileHandle->good() && m_pDBFileHandle->is_open()) {
m_pDBFileHandle->close();
}
}
}
int32_t DBFile::seek_cur_to_end_size(std::ifstream *m_pDBFileHandle, int32_t start_seek_pos)
{
if(!m_pDBFileHandle) {
return 0;
}
m_pDBFileHandle->seekg(0, std::ios::end);
if(!m_pDBFileHandle->good()) {
return 0;
}
int32_t seekg_end_size = m_pDBFileHandle->tellg();
m_pDBFileHandle->seekg(start_seek_pos, std::ios::beg);
if(!m_pDBFileHandle->good()) {
return 0;
}
int32_t seekg_cur_size = m_pDBFileHandle->tellg();
return seekg_end_size - seekg_cur_size;
}
int32_t DBFile::seek_cur_to_end_size(std::ifstream& pFile, int32_t start_seek_pos)
{
std::cout << 11111 << std::endl;
pFile.seekg(0, std::ios::end);
if(!pFile.good()) {
return 0;
}
std::cout << 22222 << std::endl;
int32_t seekg_end_size = pFile.tellg();
std::cout << 33333 << std::endl;
pFile.seekg(start_seek_pos, std::ios::beg);
std::cout << 44444 << std::endl;
if(!pFile.good()) {
return 0;
}
std::cout << 55555 << std::endl;
int32_t seekg_cur_size = pFile.tellg();
std::cout << 666666 << std::endl;
return seekg_end_size - seekg_cur_size;
}
class DBParser
{
public:
DBParser() ;
virtual ~DBParser();
int Init (const std::string DBPathFileName);
int GetHeaderSize (u_int* punHeaderSize);
int GetHeader (u_int unHeaderSize, DB_Header_t* pstHeaderInfo);
int GetNameFrameSize (u_int* punNameFrameSize);
int GetNameFrame (
u_int unOffset,
u_int unFrameSize,
DB_NameFrame_t* pstNameFrame);
int GetDistrictFrameSize (
u_int* punDistrictFrameSize);
int GetDistrictFrame (
u_int unOffset,
u_int unFrameSize,
DB_DistrictFrame_t* pstDistrictFrame);
int GetAdjacentNodeManager (
u_int unMgrOffset,
u_int unMgrSize,
DB_AdjacentNodeMgr_t* pstAdjNodeMgr);
int GetCalcRegionManagerHeader( u_int unHeaderOffset,
u_int unHeaderSize,
DB_CalcRegion_ManagerHeader_t* pstManagerHeader);
private:
std::ifstream m_hDBFileHandle ;
bool m_bIsBigEnd ;
std::string m_rp_db_file_path;
std::atomic_bool m_rp_db_file_install;
};
DBParser::DBParser() {
m_rp_db_file_path = "";
m_rp_db_file_install = false;
}
DBParser::~DBParser() {
m_rp_db_file_install = false;
if (m_hDBFileHandle.is_open()) {
m_hDBFileHandle.close() ;
}
}
int DBParser::Init (const std::string DBPathFileName)
{
m_hDBFileHandle.open(DBPathFileName , std::ios::in|std::ios::binary);
if (!m_hDBFileHandle.is_open()) {
return -1;
}
DBFile dbFile(&m_hDBFileHandle);
unsigned int unHeaderAttr = 0;
m_hDBFileHandle.read((char*)&unHeaderAttr, sizeof(unHeaderAttr)) ;
if (!m_hDBFileHandle.good()) {
return -2;
}
std::cout << "gcount = " << m_hDBFileHandle.gcount() << std::endl;
m_bIsBigEnd = DB_IsBigEnd_FromRPHeaderAttr(unHeaderAttr) ;
unsigned int unHeaderSize = 0;
std::cout << 99999 << std::endl;
m_hDBFileHandle.read((char*)&unHeaderSize, sizeof(unHeaderSize));
std::cout << 101010 << std::endl;
if (m_hDBFileHandle.gcount() != sizeof(unHeaderSize)) {
return -3;
}
std::cout << "gcount = " << m_hDBFileHandle.gcount() << std::endl;
if (unHeaderSize > 1024 * 1024) // header size 不应该大于 1M
{
return -4;
}
DB_Header_t* header = new DB_Header_t; // malloc(unHeaderSize);
if (NULL == header) {
return -5;
}
m_hDBFileHandle.seekg(0, std::ios::beg); //seek to begin
m_hDBFileHandle.read((char*)header, unHeaderSize);
if (m_hDBFileHandle.gcount() != unHeaderSize) {
free(header);
return -3;
}
m_hDBFileHandle.seekg(0, std::ios::end);
ulong fileSize = m_hDBFileHandle.tellg();
u_int frameSize = header->unFrameSize;
free(header);
if (frameSize != (u_int)fileSize) {
return -6;
}
m_rp_db_file_path = DBPathFileName;
m_rp_db_file_install = true;
m_hDBFileHandle.close();
return 0;
}
int DBParser::GetHeaderSize (u_int* punHeaderSize)
{
if (punHeaderSize == NULL) {
return -1;
}
if((true == m_rp_db_file_install) && (!m_hDBFileHandle.is_open()))
{
m_hDBFileHandle.open(m_rp_db_file_path , std::ios::in|std::ios::binary);
}
DBFile oRpFile(&m_hDBFileHandle);
if (!m_hDBFileHandle.is_open())
{
*punHeaderSize = 0;
return -2 ;
}
int size = DBFile::seek_cur_to_end_size(m_hDBFileHandle, 4);
if (!m_hDBFileHandle.good()) {
return -3;
}
if(size < sizeof(*punHeaderSize)){
return -4;
}
std::cout << 77777 << std::endl;
m_hDBFileHandle.read ((char*)punHeaderSize, sizeof (*punHeaderSize)) ;
std::cout << "gcount = " << m_hDBFileHandle.gcount() << std::endl;
std::cout << 88888 << std::endl;
if (!m_hDBFileHandle.good()) {
return false;
}
if (m_bIsBigEnd)
{
*punHeaderSize = _V_GET_LITTLE_LONG(punHeaderSize) ;
}
return 0;
}
int DBParser::GetHeader (u_int unHeaderSize,
DB_Header_t* pstHeaderInfo)
{
u_int i = 0;
Byte* pbtHeaderInfo = (Byte*)pstHeaderInfo;
DB_Level_t *pstLevelTable;
if (unHeaderSize == 0 || pstHeaderInfo == NULL) {
return -1;
}
if((true == m_rp_db_file_install) && (!m_hDBFileHandle.is_open()))
{
m_hDBFileHandle.open(m_rp_db_file_path , std::ios::in|std::ios::binary);
}
DBFile oRpFile(&m_hDBFileHandle);
if (!m_hDBFileHandle.is_open()) {
return -2;
}
m_hDBFileHandle.seekg(0, std::ios::beg);
if (!m_hDBFileHandle.good()) {
return -3;
}
/*
char tmpBuf[9016] = {0};
m_hDBFileHandle.read(tmpBuf, unHeaderSize);
*/
std::cout << "begin gcount gcount" << std::endl;
m_hDBFileHandle.read((char*)pbtHeaderInfo, unHeaderSize);
std::cout << "gcount = " << m_hDBFileHandle.gcount() << std::endl;
std::cout << "begin gcount gcount" << std::endl;
if (!m_hDBFileHandle.good()) {
return -3;
}
if (m_bIsBigEnd)
{
pstHeaderInfo->unAttr = _V_GET_LITTLE_LONG (&pstHeaderInfo->unAttr) ;
pstHeaderInfo->unHeaderSize = _V_GET_LITTLE_LONG (&pstHeaderInfo->unHeaderSize) ;
pstHeaderInfo->unFrameSize = _V_GET_LITTLE_LONG (&pstHeaderInfo->unFrameSize) ;
pstHeaderInfo->unCalcRegionMaxSize = _V_GET_LITTLE_LONG (&pstHeaderInfo->unCalcRegionMaxSize) ;
pstHeaderInfo->unInfoRegionMaxSize = _V_GET_LITTLE_LONG (&pstHeaderInfo->unInfoRegionMaxSize) ;
pstHeaderInfo->unRPLinkShapePointMaxCnt = _V_GET_LITTLE_LONG (&pstHeaderInfo->unRPLinkShapePointMaxCnt) ;
pstHeaderInfo->unNameMaxLength = _V_GET_LITTLE_LONG (&pstHeaderInfo->unNameMaxLength) ;
pstHeaderInfo->unNameFrameOffset = _V_GET_LITTLE_LONG (&pstHeaderInfo->unNameFrameOffset) ;
pstHeaderInfo->unDistrictFrameOffset = _V_GET_LITTLE_LONG (&pstHeaderInfo->unDistrictFrameOffset) ;
pstHeaderInfo->unLevelCnt = _V_GET_LITTLE_LONG (&pstHeaderInfo->unLevelCnt) ;
pstHeaderInfo->unLevelRecordSize = _V_GET_LITTLE_LONG (&pstHeaderInfo->unLevelRecordSize) ;
pstHeaderInfo->pstLevelTable = _V_GET_LITTLE_LONG (&pstHeaderInfo->pstLevelTable) ;
}
pstLevelTable = (DB_Level_t*)(pbtHeaderInfo + (u_int)(pstHeaderInfo->pstLevelTable));
if(pstLevelTable == NULL) {
return -4;
}
if (m_bIsBigEnd)
{
for (i = 0; i < pstHeaderInfo->unLevelCnt ; i++)
{
pstLevelTable->unAttr =
_V_GET_LITTLE_LONG (&pstLevelTable->unAttr) ;
pstLevelTable->unCalcRegionManagerHeaderOffset =
_V_GET_LITTLE_LONG (&pstLevelTable->unCalcRegionManagerHeaderOffset) ;
pstLevelTable->unUnCompressedCalcRegionManagerHeaderOffset =
_V_GET_LITTLE_LONG (&pstLevelTable->unUnCompressedCalcRegionManagerHeaderOffset) ;
pstLevelTable->unCalcRegionManagerHeaderSize =
_V_GET_LITTLE_LONG (&pstLevelTable->unCalcRegionManagerHeaderSize) ;
pstLevelTable->unInfoRegionManagerHeaderOffset =
_V_GET_LITTLE_LONG (&pstLevelTable->unInfoRegionManagerHeaderOffset) ;
pstLevelTable->unInfoRegionManagerHeaderSize =
_V_GET_LITTLE_LONG (&pstLevelTable->unInfoRegionManagerHeaderSize) ;
pstLevelTable->unAdjacentNodeManagerHeaderOffset =
_V_GET_LITTLE_LONG (&pstLevelTable->unAdjacentNodeManagerHeaderOffset) ;
pstLevelTable->unAdjacentNodeManagerHeaderSize =
_V_GET_LITTLE_LONG (&pstLevelTable->unAdjacentNodeManagerHeaderSize) ;
pstLevelTable = (DB_Level_t*)((Byte*)pstLevelTable + pstHeaderInfo->unLevelRecordSize );
}
}
return 0;
}
int DBParser::GetNameFrameSize(u_int* punNameFrameSize)
{
DB_Header_t stHeaderInfo ;
DB_NameFrame_t stNameFrame ;
if (punNameFrameSize == 0) {
return -1;
}
if((true == m_rp_db_file_install) && (!m_hDBFileHandle.is_open()))
{
m_hDBFileHandle.open(m_rp_db_file_path , std::ios::in|std::ios::binary);
}
DBFile oRpFile(&m_hDBFileHandle);
if (!m_hDBFileHandle.is_open()) {
return -1;
}
m_hDBFileHandle.seekg (0, std::ios::beg);
if (!m_hDBFileHandle.good()) {
return -2;
}
m_hDBFileHandle.read((char*)&stHeaderInfo, sizeof(stHeaderInfo)) ;
if (stHeaderInfo.unNameFrameOffset == 0) {
return -3;
}
if (m_bIsBigEnd)
{
stHeaderInfo.unNameFrameOffset = _V_GET_LITTLE_LONG (&stHeaderInfo.unNameFrameOffset) ;
}
m_hDBFileHandle.seekg(stHeaderInfo.unNameFrameOffset, std::ios::beg);
if (!m_hDBFileHandle.good()) {
return -2;
}
m_hDBFileHandle.read((char*)&stNameFrame.unFrameSize, sizeof(stNameFrame.unFrameSize)) ;
if (stNameFrame.unFrameSize == 0) {
return -3;
}
*punNameFrameSize = stNameFrame.unFrameSize ;
if (m_bIsBigEnd)
{
*punNameFrameSize = _V_GET_LITTLE_LONG (punNameFrameSize) ;
}
return 0;
}
int DBParser::GetNameFrame (u_int unOffset,
u_int unFrameSize,
DB_NameFrame_t* pstNameFrame)
{
u_int unTempOffset = 0;
u_int unWordsCnt ;
Byte* pbyNameFrame = (Byte*)pstNameFrame ;
u_int *punIdxTable;
u_short *pusNameTable;
if (unOffset == 0 || unFrameSize == 0 || pstNameFrame == NULL) {
return -1;
}
if((true == m_rp_db_file_install) && (!m_hDBFileHandle.is_open()))
{
m_hDBFileHandle.open(m_rp_db_file_path , std::ios::in|std::ios::binary);
}
DBFile oRpFile(&m_hDBFileHandle);
if (!m_hDBFileHandle.is_open()) {
return -2;
}
m_hDBFileHandle.seekg (unOffset, std::ios::beg);
if (!m_hDBFileHandle.good()) {
return -3;
}
m_hDBFileHandle.read ((char*)pbyNameFrame, unFrameSize) ;
if (pstNameFrame->unFrameSize == 0 ||
pstNameFrame->unNameIdxCnt == 0) {
return -4;
}
if (m_bIsBigEnd)
{
pstNameFrame->unFrameSize = _V_GET_LITTLE_LONG (&pstNameFrame->unFrameSize) ;
pstNameFrame->unStructSize = _V_GET_LITTLE_LONG (&pstNameFrame->unStructSize) ;
pstNameFrame->unNameIdxCnt = _V_GET_LITTLE_LONG (&pstNameFrame->unNameIdxCnt) ;
pstNameFrame->unNameIdxSize = _V_GET_LITTLE_LONG (&pstNameFrame->unNameIdxSize) ;
}
unTempOffset = pstNameFrame->unStructSize;
if (unTempOffset == 0 || unTempOffset % 4 != 0
|| unTempOffset != (u_int)pstNameFrame->punIdxTable) {
return -4;
}
punIdxTable = (u_int*)(pbyNameFrame + (u_int)pstNameFrame->punIdxTable) ;
if (m_bIsBigEnd)
{
for ( u_int i = 0; i < pstNameFrame->unNameIdxCnt; ++i )
{
*punIdxTable = _V_GET_LITTLE_LONG(punIdxTable);
punIdxTable = (u_int*)( (Byte*)punIdxTable + pstNameFrame->unNameIdxSize );
}
}
unTempOffset += sizeof(u_int) * pstNameFrame->unNameIdxCnt ;
unWordsCnt = unFrameSize - unTempOffset ;
if (unWordsCnt == 0 || unWordsCnt % sizeof(u_short) != 0) {
return -4;
}
unWordsCnt /= sizeof(u_short) ;
pusNameTable = (u_short*)(pbyNameFrame + (u_int)pstNameFrame->pusNameTable);
if (m_bIsBigEnd)
{
for ( u_int i = 0; i < unWordsCnt; ++i )
{
*pusNameTable = _V_GET_LITTLE_SHORT( pusNameTable );
++pusNameTable;
}
}
return 0;
}
int DBParser::GetDistrictFrameSize (
u_int* punDistrictFrameSize)
{
DB_Header_t stHeaderInfo ;
DB_DistrictFrame_t stDistrictFrame ;
if (punDistrictFrameSize == 0) {
return -1;
}
if((true == m_rp_db_file_install) && (!m_hDBFileHandle.is_open()))
{
m_hDBFileHandle.open(m_rp_db_file_path , std::ios::in|std::ios::binary);
}
DBFile oRpFile(&m_hDBFileHandle);
if (!m_hDBFileHandle.is_open()) {
return -4;
}
m_hDBFileHandle.seekg (0, std::ios::beg);
if (!m_hDBFileHandle.good()) {
return -4;
}
m_hDBFileHandle.read ((char*)&stHeaderInfo, sizeof(stHeaderInfo));
if (stHeaderInfo.unDistrictFrameOffset == 0) {
return -4;
}
if (m_bIsBigEnd)
{
stHeaderInfo.unDistrictFrameOffset = _V_GET_LITTLE_LONG (&stHeaderInfo.unDistrictFrameOffset) ;
}
m_hDBFileHandle.seekg (stHeaderInfo.unDistrictFrameOffset, std::ios::beg);
if (!m_hDBFileHandle.good()) {
return -4;
}
m_hDBFileHandle.read ((char*)&stDistrictFrame.unFrameSize, sizeof(stDistrictFrame.unFrameSize)) ;
if (stDistrictFrame.unFrameSize == 0) {
return -4;
}
*punDistrictFrameSize = stDistrictFrame.unFrameSize;
if (m_bIsBigEnd)
{
*punDistrictFrameSize = _V_GET_LITTLE_LONG (punDistrictFrameSize) ;
}
return 0;
}
int DBParser::GetDistrictFrame (
u_int unOffset,
u_int unFrameSize,
DB_DistrictFrame_t* pstDistrictFrame)
{
DB_DistrictRecord_t *pstDistrictTable;
Byte* pbyDistrictFrame = (Byte*)pstDistrictFrame ;
if (unOffset == 0 || unFrameSize == 0 || pstDistrictFrame == NULL) {
return -1;
}
if((true == m_rp_db_file_install) && (!m_hDBFileHandle.is_open()))
{
m_hDBFileHandle.open(m_rp_db_file_path , std::ios::in|std::ios::binary);
}
DBFile oRpFile(&m_hDBFileHandle);
if (!m_hDBFileHandle.is_open()) {
return -4;
}
m_hDBFileHandle.seekg (unOffset, std::ios::beg);
if (!m_hDBFileHandle.good()) {
return -4;
}
m_hDBFileHandle.read ((char*)pbyDistrictFrame, unFrameSize) ;
if (pstDistrictFrame->unFrameSize == 0 ||
pstDistrictFrame->unDistrictCnt == 0) {
return -4;
}
if (m_bIsBigEnd)
{
pstDistrictFrame->unFrameSize = _V_GET_LITTLE_LONG (&pstDistrictFrame->unFrameSize) ;
pstDistrictFrame->unStructSize = _V_GET_LITTLE_LONG (&pstDistrictFrame->unStructSize) ;
pstDistrictFrame->unDistrictCnt = _V_GET_LITTLE_LONG (&pstDistrictFrame->unDistrictCnt) ;
pstDistrictFrame->unDistrictSize = _V_GET_LITTLE_LONG (&pstDistrictFrame->unDistrictSize) ;
}
if( pstDistrictFrame->unStructSize == 0
|| pstDistrictFrame->unStructSize % 4 != 0
|| pstDistrictFrame->unStructSize != (u_int)(pstDistrictFrame->pstDistrictTable)) {
return -4;
}
pstDistrictTable = (DB_DistrictRecord_t*)
( pbyDistrictFrame + (u_int)(pstDistrictFrame->pstDistrictTable) );
if (m_bIsBigEnd)
{
for ( u_int i = 0; i < pstDistrictFrame->unDistrictCnt; ++i )
{
pstDistrictTable->usCityNameIdx = _V_GET_LITTLE_SHORT( &(pstDistrictTable->usCityNameIdx) );
pstDistrictTable->usCountyNameIdx = _V_GET_LITTLE_SHORT( &(pstDistrictTable->usCountyNameIdx) );
pstDistrictTable = (DB_DistrictRecord_t*)
( (Byte*)pstDistrictTable + pstDistrictFrame->unDistrictSize );
}
}
return 0;
}
int DBParser::GetAdjacentNodeManager (
u_int unMgrOffset,
u_int unMgrSize,
DB_AdjacentNodeMgr_t* pstAdjNodeMgr)
{
u_int i = 0;
Byte* pbtAdjNodeMgr = (Byte*)pstAdjNodeMgr ;
DB_AdjacentNode_t *pstAdjacentNode;
if (unMgrOffset == 0 || unMgrSize == 0 ||
pstAdjNodeMgr == NULL) {
return -1;
}
if((true == m_rp_db_file_install) && (!m_hDBFileHandle.is_open()))
{
m_hDBFileHandle.open(m_rp_db_file_path , std::ios::in|std::ios::binary);
}
DBFile oRpFile(&m_hDBFileHandle);
if (!m_hDBFileHandle.is_open()) {
return -4;
}
m_hDBFileHandle.seekg(unMgrOffset, std::ios::beg);
if (!m_hDBFileHandle.good()) {
return -4;
}
m_hDBFileHandle.read ((char*)pbtAdjNodeMgr, unMgrSize) ;
if (!m_hDBFileHandle.good()) {
return -4;
}
if (m_bIsBigEnd)
{
pstAdjNodeMgr->unSize = _V_GET_LITTLE_LONG (&pstAdjNodeMgr->unSize) ;
pstAdjNodeMgr->unStructSize = _V_GET_LITTLE_LONG (&pstAdjNodeMgr->unStructSize) ;
pstAdjNodeMgr->unCnt = _V_GET_LITTLE_LONG (&pstAdjNodeMgr->unCnt) ;
pstAdjNodeMgr->unRecordSize = _V_GET_LITTLE_LONG (&pstAdjNodeMgr->unRecordSize) ;
pstAdjNodeMgr->pstAdjNodes = _V_GET_LITTLE_LONG (&pstAdjNodeMgr->pstAdjNodes) ;
}
pstAdjacentNode = (DB_AdjacentNode_t*)( pbtAdjNodeMgr + (u_int)(pstAdjNodeMgr->pstAdjNodes) );
if ( m_bIsBigEnd )
{
for ( i = 0; i < pstAdjNodeMgr->unCnt; ++i )
{
pstAdjacentNode->nLongitude = _V_GET_LITTLE_LONG (
&(pstAdjacentNode->nLongitude) );
pstAdjacentNode->nLatitude = _V_GET_LITTLE_LONG (
&(pstAdjacentNode->nLatitude) );
pstAdjacentNode->stNodeID.unNodeID = _V_GET_LITTLE_LONG (
&(pstAdjacentNode->stNodeID.unNodeID) );
pstAdjacentNode->stNodeID.unNodeExtendID = _V_GET_LITTLE_LONG (
&(pstAdjacentNode->stNodeID.unNodeExtendID) );
pstAdjacentNode = (DB_AdjacentNode_t*)
( (Byte*)pstAdjacentNode + pstAdjNodeMgr->unRecordSize );
}
}
return 0;
}
int DBParser::GetCalcRegionManagerHeader (
u_int unHeaderOffset,
u_int unHeaderSize,
DB_CalcRegion_ManagerHeader_t* pstManagerHeader)
{
u_int i = 0;
Byte* pbtCalcRegionManagerHeader = (Byte*)pstManagerHeader ;
DB_CalcRegion_Idx_t *pstRegionIdxTable;
if (unHeaderOffset == 0 || unHeaderSize == 0 ||
pstManagerHeader == NULL) {
return -1;
}
if((true == m_rp_db_file_install) && (!m_hDBFileHandle.is_open()))
{
m_hDBFileHandle.open(m_rp_db_file_path , std::ios::in|std::ios::binary);
}
DBFile oRpFile(&m_hDBFileHandle);
if (!m_hDBFileHandle.is_open()) {
return -4;
}
m_hDBFileHandle.seekg (unHeaderOffset, std::ios::beg);
if (!m_hDBFileHandle.good()) {
return -4;
}
m_hDBFileHandle.read ((char*)pbtCalcRegionManagerHeader, unHeaderSize) ;
if (!m_hDBFileHandle.good()) {
return -4;
}
if (m_bIsBigEnd)
{
pstManagerHeader->unFrameSize = _V_GET_LITTLE_LONG (&pstManagerHeader->unFrameSize) ;
pstManagerHeader->unRankInfo = _V_GET_LITTLE_LONG (&pstManagerHeader->unRankInfo) ;
pstManagerHeader->unRegionCnt = _V_GET_LITTLE_LONG (&pstManagerHeader->unRegionCnt) ;
pstManagerHeader->unRegionIdxSize = _V_GET_LITTLE_LONG (&pstManagerHeader->unRegionIdxSize) ;
pstManagerHeader->pstRegionIdxTable = _V_GET_LITTLE_LONG (&pstManagerHeader->pstRegionIdxTable) ;
}
pstRegionIdxTable = (DB_CalcRegion_Idx_t*)
(pbtCalcRegionManagerHeader + (u_int)(pstManagerHeader->pstRegionIdxTable) );
if (m_bIsBigEnd)
{
for (i = 0; i < pstManagerHeader->unRegionCnt ; i++)
{
pstRegionIdxTable->unRegionOffset = _V_GET_LITTLE_LONG (
&(pstRegionIdxTable->unRegionOffset) );
pstRegionIdxTable->unUnCompressedRegionOffset = _V_GET_LITTLE_LONG (
&(pstRegionIdxTable->unUnCompressedRegionOffset) );
pstRegionIdxTable->unRegionSize = _V_GET_LITTLE_LONG (
&(pstRegionIdxTable->unRegionSize) );
pstRegionIdxTable->unCompressedRegionSize = _V_GET_LITTLE_LONG (
&(pstRegionIdxTable->unCompressedRegionSize) );
pstRegionIdxTable = (DB_CalcRegion_Idx_t*)
( (Byte*)pstRegionIdxTable + pstManagerHeader->unRegionIdxSize );
}
}
return 0;
}
int main() {
std::cout << "start test ..." << std::endl;
std::string usPathFileName = "/home/tiger/cpp/fstream/dbfile/103.rp";
DBParser dbParser;
dbParser.Init (usPathFileName);
u_int unHeaderSize = 0;
u_int unNameFrameSize = 0;
u_int unDistrictFrameSize = 0;
std::cout << dbParser.GetHeaderSize(&unHeaderSize) << " " << unHeaderSize << std::endl;
if (unHeaderSize > 0) {
DB_Header_t stHeaderInfo;
u_int size = sizeof(stHeaderInfo);
std::cout << size << " " << unHeaderSize << std::endl;
unHeaderSize > size ? unHeaderSize = size : 0;
std::cout << dbParser.GetHeader(unHeaderSize, &stHeaderInfo) << std::endl;
std::cout << stHeaderInfo.cFormatVer << std::endl;
std::cout << stHeaderInfo.cDataVer << std::endl;
std::cout << stHeaderInfo.cAuthor << std::endl;
std::cout << stHeaderInfo.cDate << std::endl;
}
std::cout << dbParser.GetNameFrameSize(&unNameFrameSize) << " " << unNameFrameSize << std::endl;
if (unNameFrameSize > 0) {
DB_NameFrame_t pstNameFrame;
//dbParser.GetNameFrame(, , );
}
std::cout << dbParser.GetDistrictFrameSize(&unDistrictFrameSize) << " " << unDistrictFrameSize << std::endl;
return 0;
}
编译执行:
g++ -g -o test test.cpp
strace -ff -o ./out ./test
1.gcount
原始代码:
系统调用:
结论:
可以看到gcount是上一次读取字节数,没有对应系统api调用
2.seekg和tellg
结论:
seekg和tellg对应系统调用为lseek
3.read
原始代码:
系统调用:
结论:
read对应系统调用为read,而且可以知道即使读取4个字节,底层系统api调用是将整个文件进行读取