预分配文件系统的存储和查询图片时,用到的函数有如下几条:
1. 初始化
首先需要创建一个句柄
PFAT32* pfat32 = PFat32_Init(devname, vwt);
然后就可以利用 pfat32
调用它的成员函数了。PFat32_Init
函数的原型如下:
/**
* @brief 初始化整个文件系统
* @param[in] filename,磁盘的节点名
* @param[in] weights,各类文件所占磁盘的比例
* @retval 非零值,句柄
* @retval NULL,失败
*/
PFAT32* PFat32_Init(char* filename, __le8* weights);
初始化函数对应释放资源函数原型,在退出文件系统时调用
/**
* @brief 释放文件系统
* @param[in] pfat32,初始化系统时,得到的句柄
*/
int PFat32_Release(PFAT32** pfat32);
2. 检查是否需要格式化
if(PFAT32_STATUS_NEED_FORMAT & pfat32->status)
如果需要格式化,那么可以调用Format
函数进行格式化。
pfat32->Format(pfat32, devSize, vwt);
函数原型如下:
/**
* @brief 对磁盘格式化
* @param[in] pfat32,初始化系统时,得到的句柄
* @param[in] devSize,磁盘大小
* @param[in] weights,预分配时,各个文件所占比例
* @retval PFAT32_OK,格式化成功
* @retval MPIC_FAIL,格式化失败
*/
int (*Format)(PFAT32* pfat32, off64_t devSize, __le8* weights);
3. 存储一张图片
/**
* @brief 写一张图片到磁盘
* @param[in] pfat32,初始化系统时,得到的句柄
* @param[in] writeInfo, 写入信息
* @retval MPIC_OK,成功
* @retval MPIC_FAIL,失败
*/
int (*WritePic)(PFAT32* pfat32, MPIC_WRITE_DATA_INFO* writeInfo);
typedef struct __MPIC_WRITE_DATA_INFO
{
__le8 chnnl; // 图片的通道信息
__le16 reason; // 存储原因
void* data; // 图片数据
__le32 size; // 图片数据长度
}MPIC_WRITE_DATA_INFO;
4. 查询图片
查询图片时,首先要调用 FindPicture
函数创建一个查询句柄,然后调用FindNextPicture
函数,可以将符合条件的图片信息遍历,并逐条返回。GetOnePicBuf
函数则可以根据返回的图片信息将指定图片的内容返回。结束查询时,调用ReleaseFindPicture
关闭查询句柄并释放资源。
(1) FindPicture 函数原型
/**
* @brief 开始一次查询图片
* @param[in] pfat32,初始化系统时,得到的句柄
* @param[in] queryInfo, 查询信息
* @retval MPIC_FAIL,失败
* @retval 其他值,查询句柄
*/
long (*FindPicture)(PFAT32* pfat32, MPIC_QUERY_REQUEST_INFO* queryInfo);
typedef struct __MPIC_QUERY_REQUEST_INFO
{
__le32 startTime;
__le32 endTime;
__le16 expectedCnt; // 本次需要查询的期望数目,实际超过,则返回该值。不足则返回实际值。
__le8 chnnl;
}MPIC_QUERY_REQUEST_INFO;
(2) FindNextPicture 函数原型
/**
* @brief 查询下一张图片的信息
* @param[in] pfat32,初始化系统时,得到的句柄
* @param[in] findHandle,FindPicture 函数返回的句柄
* @param[out] outFindData,查询到的信息
* @retval MPIC_OK,成功
* @retval MPIC_FINDNEXT_NOMOREPIC,没有更多的图片了
* @retval MPIC_FAIL,失败
*/
int (*FindNextPicture)(PFAT32* pfat32, long findHandle, MPIC_QUERY_RES_INFO* outFindData);
typedef struct __MPIC_QUERY_RES_INFO
{
__le32 id; // 图片的唯一标志
__le32 storTime; // 图片的存储时间
__le32 size; // 图片大小
__le16 reason; // 存储原因
__le8 chnnl; // 通道
}MPIC_QUERY_RES_INFO;
(3) GetOnePicBuf 函数原型
/**
* @brief 根据picInfoID从磁盘读出一张图片的内容
* @param[in] pfat32,初始化系统时,得到的句柄
* @param[in] picInfoID,需要查询的图片的 id,FindNextPicture 的返回值包含此信息
* @param[out] outBuf,查询到的图片内容
* @param[out] outBufLen,查询到的图片长度
* @retval MPIC_OK,成功
* @retval MPIC_FAIL,失败
*/
int (*GetOnePicBuf)(PFAT32* pfat32, __le32 picInfoID, void* outBuf, __le32* outBufLen);
(4) ReleaseFindPicture 函数原型
/**
* @brief 关闭查询句柄,释放资源
* @param[in] findHandle,FindPicture 函数返回的句柄
* @retval MPIC_OK,成功
* @retval MPIC_FAIL,失败
*/
int (*ReleaseFindPicture)(long findHandle);
以下是使用预分配文件系统存储和查询图片的例子。
static off64_t GetFileSize(char* devname)
{
int fd = 0;
struct stat64 buf; // stat 获取比较快,如果失败了,用下面那个方法
if(stat64(devname, &buf)<0){
printf("cannot open file\n");
goto anotherMethod;
}
if(0!=buf.st_size)
return buf.st_size;
anotherMethod:
fd = open(devname, O_RDWR);
if(0 > fd){
printf("%s open error, Message: %s\n", __FUNCTION__, strerror(errno));
return MPIC_FAIL;
}
off64_t len = lseek64(fd, 0, SEEK_END);
close(fd);
return len;
}
int main()
{
char devname[] = "/dev/mmcblk0";
// char devname[] = "../../tmp/disk";
__le8 vwt[] = {30, 37, 30, 1, 1, 1}; // vwt/100,表示各个文件的占总空间的比例
/***************************************************************************
测试内容:将 testImage 重复写入磁盘,再读出,写到 queriedPath 里
***************************************************************************/
char testImage[] = "../../tmp/testImage/1.jpg";
char queriedPath[] = "../../tmp/queriedData";
char saveName[128] = {0};
// 将 image 读入 imageBuf
off64_t imageLen = GetFileSize(testImage);
char* imageBuf = (char*)malloc(imageLen);
int fd = open(testImage, O_RDONLY);
read(fd, imageBuf, imageLen);
close(fd);
/***************************************************************************
初始化
***************************************************************************/
PFAT32* pf = PFat32_Init(devname, vwt);
if(NULL == pf){
printf("PFat32_Init failed\n");
return 0;
}
// 检查是否需要格式化
if(PFAT32_STATUS_NEED_FORMAT & pf->status){
printf("now formatting...\n\n");
pf->Format(pf, pf->devSize, vwt);
printf("\nformatting finished.\n\n");
}
/***************************************************************************
测试写入
***************************************************************************/
#define test_writein
#ifdef test_writein
__le16 loopCnt = 1000, backup = loopCnt;
MPIC_WRITE_DATA_INFO writeInfoPic;
writeInfoPic.reason = PICINDEX_REASON_MANUAL;
writeInfoPic.chnnl = 1;
writeInfoPic.data = imageBuf;
writeInfoPic.size = imageLen;
TimeStart();
while(loopCnt--){
// 写一张图片
pf->WritePic(pf, &writeInfoPic);
}
long spendTime = TimePrint("write pictures");
printf("\nimageSize: %lld B, totalSize: %0.3f kB, speed: %0.3f kB/s\n", imageLen,
((double)backup*(double)imageLen/1024.0),
((double)backup*(double)imageLen/1024.0)/((double)spendTime/1e6));
#endif
/***************************************************************************
测试读出
***************************************************************************/
#define test_readout
#ifdef test_readout
MPIC_QUERY_REQUEST_INFO req;
req.startTime = 1531274016;
req.endTime = 0x5c39e3db;
req.expectedCnt = 10;
req.chnnl = 1;
TimeStart();
long findHandle = pf->FindPicture(pf, &req);
// 逐条查询,把信息写出到指定位置
MPIC_QUERY_RES_INFO res;
FILE* fp = 0;
int ij = 0;
char* picBuf = 0;
__le32 picBufLen = 0;
int isEnd = 0;
while(1){
isEnd = pf->FindNextPicture(pf, findHandle, &res);
printf("isEnd: %d, storTime: %d, id: %d, chnnl: %d, reason: %d, size: %d\n",
isEnd, res.storTime, res.id, res.chnnl, res.reason, res.size);
if(0!=isEnd)
break;
picBuf = (char*)malloc(res.size);
if(!picBuf){
printf("malloc failed\n");
goto release;
}
pf->GetOnePicBuf(pf, res.id, picBuf, &picBufLen);
sprintf(saveName, "%s/image%03d.jpg", queriedPath, ij);
fp = fopen(saveName, "wb");
fwrite(picBuf, picBufLen, 1, fp);
fclose(fp);
free(picBuf);
ij++;
}
pf->ReleaseFindPicture(findHandle);
TimePrint("query pictures");
#endif
/***************************************************************************
释放资源
***************************************************************************/
release:
PFat32_Release(&pf);
free(imageBuf);
imageBuf = NULL;
printf("\nfinished!\n");
return 0;
}