经过之前的几次试验 决定使用json记录打包文件信息

#include "Package.h"
#include "json/json.h"
#include <string>
#include <iostream>
 
/**************************************************************
技术博客
http://www.cnblogs.com/itdef/
  
技术交流群
群号码:324164944
  
欢迎c c++ windows驱动爱好者 服务器程序员沟通交流
**************************************************************/
 
bool Package::CreatePackage(const char* packFileName) {
    bool bRet = false;
 
    fpPackage_ = fopen(packFileName,"wb+");
    if (NULL == fpPackage_)
        return bRet;
 
    bRet = true;
    return bRet;
}
 
void Package::AddFileToList(const char* fileName) {
    fileList.push_back(fileName);
}
 
bool Package::OpenPackageForUnPack(const char* packFileName) {
    if (NULL != fpPackage_)
        fclose(fpPackage_);
 
    fpPackage_ = fopen(packFileName, "rb");
    if (NULL == fpPackage_)
        return false;
 
    return true;
}
 
bool Package::CopyFileContent(FILE* src, FILE* dsc) {
    char* buf = new char[CopyBufSize];
    if (NULL == buf)
        return false;
 
    while (1) {
        int nReadBytes = fread(buf,1, CopyBufSize, src);
        //写入包裹
        fwrite(buf, 1, nReadBytes, dsc);
        //如果读取到的数据比缓冲区小,那么说明读取结束了
        if (nReadBytes < sizeof(buf))
        {
            break;
        }
    }
    //fflush是确保我们的数据写入到磁盘上了
    fflush(dsc);
    return true;
}
 
bool  Package::PackageOneFile(const char*name)
{
    bool bRet = false;
 
    FILE* fp = fopen(name, "rb");
    if (NULL == fp)
    return bRet;
 
    //获取文件长度
    _fseeki64(fp, 0, SEEK_END); //定位到文件末
    __int64 filelength = _ftelli64(fp);
    _fseeki64(fp, 0, SEEK_SET);
 
    //获取PACKAGE文件当前偏移
    __int64 currentOffset = _ftelli64(fpPackage_);
 
    //开始打包
    CopyFileContent(fp, fpPackage_);
 
    FILEINFO fileInfo;
    fileInfo.filename = name;
    fileInfo.fileSize = filelength;
    fileInfo.offsetInPackFile = currentOffset;
 
    fileInfoList.push_back(fileInfo);
    fclose(fp);
    return bRet;
}
 
bool Package::GetUnpackFileInfo() {
    fileInfoList.clear();
    __int64 jsonOffset = 0;
    fread(&jsonOffset,1,sizeof(jsonOffset), fpPackage_);
 
    //获取文件长度
    _fseeki64(fpPackage_, 0, SEEK_END); //定位到文件末
    __int64 filelength = _ftelli64(fpPackage_);
    _fseeki64(fpPackage_, 0, SEEK_SET);
 
    _fseeki64(fpPackage_, jsonOffset, SEEK_SET);
    char* jsonBuf = new char[filelength - jsonOffset];
    if (NULL == jsonBuf)
        return false;
    fread(jsonBuf,filelength - jsonOffset,1, fpPackage_);
 
    //解析json字符串
    Json::Reader pJsonParser;;
    Json::Value tempVal;
 
    if (!pJsonParser.parse(jsonBuf, tempVal))
    {
        std::cout << "parse error" << std::endl;
        delete[] jsonBuf;
        return false;
    }
 
    Json::Value array = tempVal["array"];
    for (int i = 0; i < array.size(); i++) {
        std::cout << array[i]["Filename"].asString() << std::endl;
        std::cout << array[i]["FileSize"].asInt64() << std::endl;
        std::cout << array[i]["Offset"].asInt64() << std::endl;
    }
 
    delete[] jsonBuf;
    return true;
}
 
 
bool Package::WriteFileInfoToPackFile() {
 
    //获取PACKAGE文件当前偏移 写入JSON文件信息的偏移
    __int64 currentOffset = _ftelli64(fpPackage_);
    //生成JSON
    Json::Value root;
    Json::Value array;
    Json::FastWriter writer;
    Json::Value fileInfo;
 
    for (std::deque<FILEINFO>::iterator it = fileInfoList.begin();
        it != fileInfoList.end(); it++) {
        fileInfo["Filename"] = it->filename;
        fileInfo["FileSize"] = it->fileSize;
        fileInfo["Offset"] = it->offsetInPackFile;
        array.append(fileInfo);
    }
    root["array"] = array;
     
    std::string s = writer.write(root);
 
    //写入文件信息
    fwrite(s.c_str(),1,s.size(), fpPackage_);
 
    //跳转到文件头 写入JOSN偏移
    _fseeki64(fpPackage_, 0, SEEK_SET);
    fwrite(&currentOffset,1,sizeof(currentOffset), fpPackage_);
    fflush(fpPackage_);
    return true;
}
 
bool Package::PackFile() {
    bool bRet = false;
    //预留 打包文件的信息的偏移位置
    __int64 jsonOffset = 0;
    fwrite(&jsonOffset, 1, sizeof(jsonOffset), fpPackage_);
    for (std::deque<std::string>::iterator it = fileList.begin();
        it != fileList.end(); it++) {
        std::string fileName = *it;
        PackageOneFile(fileName.c_str());
    }
    fileList.clear();
    WriteFileInfoToPackFile();
 
    return bRet;
}

打包文件格式如下

文件信息格式类似

代码运行结果

具体代码见

http://www.oschina.net/code/snippet_614253_56938

文件打包代码更新 使用json记录打包文件信息的更多相关文章

  1. requirejs 多页面,多js 打包代码,requirejs多对多打包

    这段代码来自 http://stackoverflow.com/questions/20583812/grunt-requirejs-optimizer-for-a-multi-app-project ...

  2. requirejs 多页面,多js 打包代码,requirejs多对多打包【收藏】

    这段代码来自 http://stackoverflow.com/questions/20583812/grunt-requirejs-optimizer-for-a-multi-app-project ...

  3. 【python】将json串写入文件,并以json格式读取出来

    写json--json.dumps 代码: import json #要写入文件的json串(dict格式) result ={', 'https://appapi.xxxx.com/appapi/b ...

  4. [转] 三种Python下载url并保存文件的代码

    原文 三种Python下载url并保存文件的代码 利用程序自己编写下载文件挺有意思的. Python中最流行的方法就是通过Http利用urllib或者urllib2模块. 当然你也可以利用ftplib ...

  5. 用winform实现一个B/S代码更新打包工具

    一个.net程序员必须拥有的能力就是可以随时随地写出一个自己需要的小工具,于是记录一下我的个人工具吧. 新建一个窗体应用项目,代码如下: namespace 打包工具 { partial class ...

  6. 建立apk定时自动打包系统第三篇——代码自动更新、APP自动打包系统

    我们的思路是每天下班后团队各成员在指定的时间(例如下午18:30)之前把各自的代码上传到SVN,然后服务器在指定的时间(例如下午18:30)更新代码.执行ant 打包命令.最后将apk包存放在指定目录 ...

  7. Linux 学习记录 二 (文件的打包压缩).

     前言:本文参考<鸟哥的Linux 私房菜>,如有说的不对的地方,还请指正!谢谢!  环境:Centos 6.4    和window不同,在Linux压缩文件需要注意的是,压缩后的文件会 ...

  8. Linux 学习记录二(文件的打包压缩).

    和 window不同,在Linux压缩文件需要注意的是,压缩后的文件会把源文件给替代,无论是gzip.bzip2.xz 均不支持压缩目录,要达到压缩目录的目的,需要用到tar指令.   gzip 压缩 ...

  9. Web API删除JSON格式的文件记录

    Insus.NET的系列Web Api学习文章,这篇算是计划中最后一篇了,删除JSON格式的文件记录.前一篇<Web Api其中的PUT功能演示>http://www.cnblogs.co ...

随机推荐

  1. 【java基础】ThreadLocal的实现原理

    [一]:ThreadLocal对象的大体实现原理===>当前线程对象有一个ThreadLocal.ThreadLocalMap属性.===>声明的ThreadLocal对象最终存储在当前线 ...

  2. C#在64位操作系统上连接Oracle的问题和解决方案

    C#使用System.Data.OracleClient连接Oracle数据库.之前在WinXP上正常运行的程序移植到Windows 2008 x64上之后就连不上数据库了.错误信息如下: 尝试加载O ...

  3. CCNode的属性说明

    class CC_DLL CCNode : public CCObject { protected://属性列表 float m_fRotationX; ///x轴旋转角度 float m_fRota ...

  4. Linux下利用Shell使PHP并发采集淘宝产品

    上次项目中用到<<PHP采集淘宝商品>> 此方法有一个缺点,就是执行效率问题.一个商品采集平均需要0.8秒.那10000个商品采集完需要2个半小时. 首先想到的解决办法是并发. ...

  5. VirtualBox的端口映射其实很好理解

    还是和以前百度的另一个知识点一样,我真不明白网上那些人要做什么,明明很简单的事,干嘛非要讲的那么复杂,就是为了让人觉得你很高手?很厉害? 名称:随便起的,基于好记的原则,你的什么应用在使用这一条端口转 ...

  6. Java 从原字符串中截取一个新的字符串 subString()

    Java 手册 substring public String substring(int beginIndex) 返回一个新的字符串,它是此字符串的一个子字符串.该子字符串从指定索引处的字符开始,直 ...

  7. 控件m

    窗体的事件:删除事件:先将事件页面里面的挂好的事件删除,再删后台代码里面的事件 Panel是一个容器 1.Label -- 文本显示工具Text:显示的文字取值.赋值:lable1.Text 2.Te ...

  8. Hive默认分割符

    1.Hive默认的分隔符 Hive的表数据,不管导出到HDFS还是本地文件系统,如果用户在导出时没有指定分割符,那么Hive表的数据在写入文件时,会使用默认的分隔符作为列分隔符,该默认的分割是“CTR ...

  9. centos7.3下apache搭建django[未成功]

    1 apache肯定已经按照完毕了, 如果没有  yum install httpd yum install mod_wsgi 安装完成之后,mod_wsgi.so会在Apache的modules目录 ...

  10. C# 中带有中国农历的日期选择控件

    开源一款自己刚开始接触 C# 时开发的带有农历信息的日期选择控件,记得那时还是在2010年的寒假期间做的这个东西.刚开始接触 C# 时,使用WinForm来开发桌面程序,觉得简直是简单又迅速,由于 C ...