经过之前的几次试验 决定使用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. nginx中使用 md5

    core/ngx_md5.h 头文件 /* * Copyright (C) Igor Sysoev * Copyright (C) Nginx, Inc. */ #ifndef _NGX_MD5_H_ ...

  2. 转 How do GraphQL remote schemas work

    文章转自 prisma 官方博客,写的很不错 In this article, we want to understand how we can use any existing GraphQL AP ...

  3. CentOS7 RPM安装 rabbitmqDownloads on Bintray

    下载 0依赖Erlang RPM for RabbitMQ包(https://github.com/rabbitmq/erlang-rpm) https://dl.bintray.com/rabbit ...

  4. 【monkeyrunner】monkeyrunner 的的方法介绍

    1.用法:MonkeyRunner.alert(message,title,okTitle) 执行当前脚本弹出一个警示对话框,用户关闭对话框后脚本才结束. message:会话弹出的内容title:会 ...

  5. (转)html中使用表单和input file上传图片

    本文转载自:http://hi.baidu.com/love_1210/item/120e452b42b2a854c38d59eb 客户端代码: <form name="form1&q ...

  6. py基础4--迭代器、装饰器、软件开发规范

    本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1. 列表生成式,迭代器&生成器 列表生成式 我现在有个需求, ...

  7. 详解Oracle的几种分页查询语句

    转载自:http://database.51cto.com/art/200904/118737.htm 分页查询格式: SELECT * FROM (SELECT A.*, ROWNUM RN FRO ...

  8. c#中的dynamic类型

    dynamic是C#4.0引入的全新类型,它允许其操作略过编译期类型检查,而在运行时期处理. dynamic类型在大多数情况下和object类似,不同点在于编译器对于dynamic类型的 数据不做进一 ...

  9. Oracle中 HWM与数据库性能的探讨

    链接:http://www.eygle.com/archives/2011/11/oracle_hwm_tuning.html 本文讨论的是oracle中关于table的HWM的内容,主要包括这样几个 ...

  10. OpenCL 图像卷积 1

    ▶ 书上的代码改进而成,从文件读入一张 256 阶灰度图,按照给定的卷积窗口计算卷积,并输出到文件中. ● 代码,使用 9 格的均值窗口,居然硬读写 .bmp 文件,算是了解一下该文件的具体格式,留作 ...