经过之前的几次试验 决定使用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. Ambiguous reference to member 'dataTask(with:completionHandle:)'错误

    在研究IOS的网络请求过程中,因为NSURLConnection已经过时,需要引用到URLSession var url:NSURL=NSURL(string: "http://3g.163 ...

  2. 自动化工具 Python 调 Jmeter 执行参数化 jmx 脚本

    烦透了jmeter输入如下鬼命令: Jmeter -n -t {tmpjmxfile} -l {csvfilename} -e -o {htmlreportpath} 尤其是{htmlreportpa ...

  3. 用原生 JS 实现双向绑定及应用实例

    写在前面: 所谓的双向绑定,无非是从界面的操作能实时反映到数据,数据的变更也能实时展现到界面.angular封装了双向绑定的方法,使双向绑定变得十分简单.但是在有些场景下(比如下面那个场景),不能使用 ...

  4. vim之vundle

    git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle,下载到本地 gvim ~/.vimrc set nocompat ...

  5. RecordingOptions录制设置选项

    1.录制思考时间 2.录制方式 3.自定义证书 4.非资源选项

  6. 一些部署django用到的linux命令

    mv untitled45/ /1601F/wang/ 将XXXX移动到XXX,也可以用于给XXX重新命名 zip -r -q -o hello.zip  /1601F/3/untitled45 安静 ...

  7. UDP协议发包的使用(DatagramSocket、DatagramPacket)

    1.UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传 ...

  8. canvas绘制曲线

    canvas绘制曲线 方法 quadraticCurveTo(cp1x, cp1y, x, y) 只有一个控制点的贝塞尔曲线(其实就是控制点分别与起始点和结束点连线的公切线) bezierCurveT ...

  9. guicorn 是什么

    guicorn 是什么? 在回答问题之前我们先来看看 web服务器的典型过程[1] 1. 建立链接:如果没有连接,要建立连接 2. 接收请求:对客户端发来的请求进行解析. 3. 处理请求:转发给预定义 ...

  10. lamp。查看版本

    [root@localhost ~]# php -vPHP 5.2.16 (cli) (built: Dec 17 2010 14:09:03) Copyright (c) 1997-2010 The ...