经过之前的几次试验 决定使用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. Android实现带图标的ListView

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/bear_huangzhen/article/details/23991119 Android实现带图 ...

  2. FastAdmin 的前端环境怎么安装?

    FastAdmin 的前端环境怎么安装? 安装 Git 安装 Node.js 安装 cnpm 安装 bower 开始安装 FastAdmin 的前端组件 bower install bower upd ...

  3. 如何查看MySql的BLOB内容

    一款Mysql的工具: SQLyog. 强项在于可以把blob的内容直接显示出来. 我觉得其实做产品能够活挺厉害,因为你做的东西确实为客户提供价值:在云云产品之中,能够让客户发现你并使用,购买你的产品 ...

  4. Web验证方式(2)--Form Authentication

    Form验证方式并不是HTTP标准,而是在微软ASP.NET Web框架下提供的一种验证方式.其大致流程如下: 在上图的流程中,ASP.NET框架提供了如下支持类:( FormsAuthenticat ...

  5. NLTK在自然语言处理

    nltk-data.zip 本文主要是总结最近学习的论文.书籍相关知识,主要是Natural Language Pracessing(自然语言处理,简称NLP)和Python挖掘维基百科Infobox ...

  6. erlang程序发布的时候需要注意的地方

    假如你的程序依赖三方application,比如cowboy,启动三方程序有两种方式 在erl脚本里面手工启动,这种在使用rebar generate打包的时候和发布beam的时候都可以用 appli ...

  7. java对图片进行操作,仅仅是小demo

    package com.cy.thumb; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io ...

  8. PhpStorm 配置在浏览器中打开文件

    这东东中文资料太少- -鼓捣了好久才有结果 点击File-Settings-Deployment .点+按钮增加服务器 Mapping 设置工程路径等 点击 Edit Confi 这东东中文资料太少- ...

  9. 熟练的使用CIFAR-10数据集

    CIFIR-10是一套包含60000张,大小为32x32的十分类图片数据集,其中50000张被分为训练数据,10000张被分为测试数据,http://www.cs.toronto.edu/~kriz/ ...

  10. Python 中的属性访问与描述符

    在Python中,对于一个对象的属性访问,我们一般采用的是点(.)属性运算符进行操作.例如,有一个类实例对象foo,它有一个name属性,那便可以使用foo.name对此属性进行访问.一般而言,点(. ...