经过之前的几次试验 决定使用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. Pgsql和Mysql的对比

    工作中用过这两个数据库,但都不是太深入,仅限于用而已,但给我留下的印象就是Pgsql更好些,因为这两个库我都遇到过数据丢失的问题,前者我通过网上方法加自己的判断有惊无险的恢复了,而后者搜索各种资料加问 ...

  2. (转)性能分析之-- JAVA Thread Dump 分析综述

    原文链接:http://blog.csdn.net/rachel_luo/article/details/8920596 最近在做性能测试,需要对线程堆栈进行分析,在网上收集了一些资料,学习完后,将相 ...

  3. linux之 ssh连接服务器,WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!

    [root@zk01 ~]# ssh localhost@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ WARNING: RE ...

  4. centOS6.6环境下安装AMP

    LAMP --  Linux Apache MySQL PHP 在CentOS安装的顺序,我一般是Apache -> MySQL -> PHP 第一步.安装并配置Apache 1.使用yu ...

  5. 【pc杂谈】win7系统通过虚拟网卡共享wifi

    用管理员权限进入dos命令行 启用并设定虚拟WiFi网卡:netsh wlan set hostednetwork mode=allow  ssid=paulnet key=paulwinflo(注意 ...

  6. 1、hadoop HA分布式集群搭建

    概述 hadoop2中NameNode可以有多个(目前只支持2个).每一个都有相同的职能.一个是active状态的,一个是standby状态的.当集群运行时,只有active状态的NameNode是正 ...

  7. 安装wamp 缺少msvcr100.dll

    在一台新电脑上安装wampsever 这是百度上的解决方案,http://jingyan.baidu.com/article/0320e2c1eb49681b87507ba4.html 本人亲测 第一 ...

  8. php ini_set更改php.ini配置,通过它修改php.in达到php上传文件大小限制是不行的,除非修改.htaccess文件

    PHP ini_set() 无效的原因:如题:我租的是虚拟主机,php.ini里的upload_max_filesize是默认的2M,要直接修改php.ini文件是不可能的.我如果想上传超过2M的怎么 ...

  9. 20181123_SQL Server 2008_找出以逗号分隔的字符串中最大的数字

    --select [dbo].[Fun_GetMaxNum]('棉 20%,麻 190%,涤纶60%') CREATE FUNCTION [dbo].[Fun_GetMaxNum] ( @StrAll ...

  10. Centos编译Redis4.0.9源码过程记录

    mkdir /home/redis cd /home/redis 下载源码 wget https://codeload.github.com/antirez/redis/tar/4.0.9 解压源码包 ...