简易文件打包程序

2023-05-16

对指定目录下面的文件进行打包。

简易解包程序参考博客另外一篇文章:
http://blog.csdn.net/yi_ming_he/article/details/77689453

打包方式:
把目录下面的文件名,文件大小,偏移位置,文件内容,以索引形式保存在打包文件中

使用方法:

1.packetfiles.exe为打包程序
2.运行时使用管理员权限
3.可以直接运行packetfiles.exe进行打包,只需要把需要打包的文件放在与packetfiles.exe同一级的input目录即可(如果没有该目录需要手动创建在把文件扔进去),生成的打包文件默认是files.pak,位于和packetfiles.exe文件同一级目录
4.另外一种打包方式是通过指定命令行参数设置打包的目录和打包后的文件路径,如下图所示:
这里写图片描述

PacketFiles.h:

#pragma once

struct MyFileData
{
    int nOffset;//文件相对于压缩包文件的偏移
    int nFileSize;//文件的Size
    int nFileNameLength;//文件名包含的字符个数
    CString strFileName;//文件名
    CString strFilePath;//文件路径,用于把文件打包进来

    MyFileData()
    {
        nOffset = 0;
        nFileSize = 0;
        nFileNameLength = 0;
    }
};

class CPacketFiles
{
public:
    CPacketFiles();
    ~CPacketFiles();

    void PacketFiles(LPCTSTR lpDir, LPCTSTR lpOutFilePath);//传入需要打包的文件夹目录

private:
    void _PathAddBackSlach(CString& strPath);
    void _GetFileInfo(LPCTSTR lpDir);
    void _GetPacketInfo();
    void _DoPacketFiles(LPCTSTR lpOutFilePath);

private:
    int m_nIndexTableSize;//索引表Size
    int m_nIndexTableElementCount;//索引表包含元素个数
    std::vector<MyFileData> m_vecFileData;
};

PacketFiles.cpp

#include "stdafx.h"
#include "PacketFiles.h"

using std::fstream;

CPacketFiles::CPacketFiles()
{
    m_nIndexTableSize = 0;
    m_nIndexTableElementCount = 0;
    m_vecFileData.clear();
}

CPacketFiles::~CPacketFiles()
{
}

void CPacketFiles::PacketFiles(LPCTSTR lpDir, LPCTSTR lpOutFilePath)
{
    if (NULL == lpDir || NULL == lpOutFilePath)
        return;

    _GetFileInfo(lpDir);
    _GetPacketInfo();
    _DoPacketFiles(lpOutFilePath);
}

void CPacketFiles::_PathAddBackSlach(CString& strPath)
{
    CString strTemp;
    strTemp = strPath.Right(1);

    if (strTemp != _T("\\") && strTemp != _T("/"))
        strPath.Append(_T("\\"));
}

void CPacketFiles::_GetFileInfo(LPCTSTR lpDir)
{
    CString strDir(lpDir);
    CString strFindPath;
    WIN32_FIND_DATA fData;
    HANDLE hFind = INVALID_HANDLE_VALUE;
    _PathAddBackSlach(strDir);
    strFindPath.Format(_T("%s*.*"), strDir);

    hFind = ::FindFirstFile(strFindPath, &fData);
    if (hFind == INVALID_HANDLE_VALUE)
        goto Exit0;

    do
    {
        if (0 == _tcscmp(fData.cFileName, _T(".")) ||
            0 == _tcscmp(fData.cFileName, _T("..")))
            continue;

        if (fData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
            continue;
        }
        else
        {
            CString strFileName = fData.cFileName;
            CString strFilePath = strDir + strFileName;
            MyFileData myFileData;
            myFileData.nFileNameLength = strFileName.GetLength();
            myFileData.strFileName = strFileName;
            myFileData.strFilePath = strFilePath;

            fstream file;
            file.open(CW2A(strFilePath), std::ios::in | std::ios::binary);
            file.seekp(0, std::ios::end);
            std::streamoff len = file.tellp();
            myFileData.nFileSize = (int)len;
            file.close();

            m_vecFileData.push_back(myFileData);
        }
    } while (::FindNextFile(hFind, &fData) != 0);

Exit0:
    if (hFind != INVALID_HANDLE_VALUE)
        ::FindClose(hFind);
}

void CPacketFiles::_GetPacketInfo()
{
    m_nIndexTableElementCount = m_vecFileData.size();
    int nOffSet = 0;
    m_nIndexTableSize = 4;//这个是指文件个数
    for (int i = 0; i < (int)m_vecFileData.size(); i++)
    {
        m_nIndexTableSize += (sizeof(int) + sizeof(int) + sizeof(int) + m_vecFileData[i].nFileNameLength);//前面3个分别是偏移,文件大小,文件名长度
        m_vecFileData[i].nOffset = nOffSet;
        nOffSet += m_vecFileData[i].nFileSize;
    }
}

void CPacketFiles::_DoPacketFiles(LPCTSTR lpOutFilePath)
{
    CString strOutFilePath(lpOutFilePath);
    fstream dstFile;
    fstream srcFile;
    dstFile.open(CW2A(strOutFilePath), std::ios::out | std::ios::binary);
    dstFile.write((char *)&m_nIndexTableSize, sizeof(int));
    dstFile.write((char *)&m_nIndexTableElementCount, sizeof(int));

    for (int i = 0; i < (int)m_vecFileData.size(); i++)
    {
        dstFile.write((char *)&m_vecFileData[i].nOffset, sizeof(int));
        dstFile.write((char *)&m_vecFileData[i].nFileSize, sizeof(int));
        dstFile.write((char *)&m_vecFileData[i].nFileNameLength, sizeof(int));
        CString strFileName = m_vecFileData[i].strFileName;
        dstFile.write((char *)CW2A(strFileName), m_vecFileData[i].nFileNameLength);
    }

    for (int i = 0; i < (int)m_vecFileData.size(); i++)
    {
        srcFile.open(CW2A(m_vecFileData[i].strFilePath), std::ios::in | std::ios::binary);
        dstFile.seekp(m_nIndexTableSize + 4 + m_vecFileData[i].nOffset, std::ios::beg);//定位写数据的起始位置
        for (int j = 0; j < m_vecFileData[i].nFileSize; j++)
            dstFile.put(srcFile.get());
        srcFile.close();
    }
    dstFile.close();
}

main.cpp

#include "stdafx.h"
#include "PacketFiles.h"

CString GetCurrentModuleDir()
{
    TCHAR szPath[MAX_PATH + 1] = { 0 };
    if (0 == ::GetModuleFileName((HMODULE)&__ImageBase, szPath, MAX_PATH))
        return L"";

    ::PathRemoveFileSpec(szPath);
    CString strDir = szPath;
    return strDir;
}

int _tmain(int argc, _TCHAR* argv[])
{
    CString strInputDir = GetCurrentModuleDir() + L"\\input\\";
    CString strOutFilePath = GetCurrentModuleDir() + L"\\files.pak";
    if (argc == 3)
    {
        strInputDir = argv[1];
        strOutFilePath = argv[2];
    }

    CPacketFiles files;
    files.PacketFiles(strInputDir, strOutFilePath);
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

简易文件打包程序 的相关文章

  • 数传电台术语详解

    数传电台 xff08 data radio xff09 是指借助DSP 技术和无线电技术实现的高性能专业数据传输电台 数传电台的使用从最早的按键电码 电报 模拟电台加无线MODEM xff0c 发展到目前的数字电台和DSP 软件无线电 xf
  • 无线数传电台的发展趋势

    摘自 专业无线通信 传媒 无线数传电台作为一种最简洁的通行方式 xff0c 具有很长的历史 xff0c 其基本的特征是通联方便 简捷 xff0c 同时也存在着封闭性强的特点 xff0c 正是由于上述原因 xff0c 无线数传电台产品的生命期
  • wget 提交post请求

    格式 xff1a wget post data 34 item1 61 value1 amp item2 61 value2 34 http xxx xxx com 示例 xff1a wget post data 34 username 6
  • 欧拉角、轴角与四元数

    1 欧拉角 欧拉角使用最简单的x y z值来分别表示在x xff0c y xff0c z轴上的旋转角度 xff0c 其取值为0 360 或者0 2pi xff09 xff0c 一般使用roll xff0c pitch xff0c yaw来表
  • Linux 系统投屏显示

    最近使用电脑跑Linux时需要用到显示器投屏 xff0c 于是快乐的拿上我的笔记本连上了投影仪 emmm 然鹅并没有什么卵用 果断问度娘 xff0c 看到好多人说使用xrandr命令设置 xff0c 于是便上手试了下 xff0c 看到我运行
  • C++ 判断一个 int 型整数是否为 2 的 N 次方(幂次)

    判断一个整数是否为2的幂次方法有以下几种 xff1a 1 循环除2 这是最简单最好理解的方式 对于一个数如果是2的幂次 xff0c 则其肯定可以被2一直整除直到其值为1 所以可以通过一个while循环判断 xff1a void judge
  • Dijkstra算法图文详解

    Dijkstra算法算是贪心思想实现的 xff0c 首先把起点到所有点的距离存下来找个最短的 xff0c 然后松弛一次再找出最短的 xff0c 所谓的松弛操作就是 xff0c 遍历一遍看通过刚刚找到的距离最短的点作为中转站会不会更近 xff
  • 需求中如何画用例图

    UML用例图 用例图主要用来图示化系统的主事件流程 xff0c 它主要用来描述客户的需求 xff0c 即用户希望系统具备的完成一定功能的动作 xff0c 通俗地理解用例就是软件的功能模块 xff0c 所以是设计系统分析阶段的起点 xff0c
  • 反光板导航SLAM(二)VEnus代码浅析

    上一章简单介绍了VEnus中几个主要函数的作用 xff0c 这里详细展开看一下每个函数的具体思路 xff0c 通过研究具体的代码我们可以简单了解VEnus中对于反光柱定位的具体流程 1 IntensityExtraction Extract
  • TEB算法详解(TebLocalPlannerROS::computeVelocityCommands(3))

    第一章主要分析了teb算法的准备条件 xff0c 包括获取当前位姿与速度 对全局路径的裁减以获取局部路径等以及局部地图的获取等 第二章主要讲述了在获取前置条件后 xff0c 如何根据前置条件进行位姿优化 xff0c teb的路径优化主要是调
  • TEB算法详解 参数详解

    teb算法的基本思路之前已经看完了 xff0c 今天主要看一下teb算法的参数配置文件 xff0c 分析一下每个配置参数的作用 xff1a teb的参数主要可以包含以下几个部分 xff1a 1 Trajectory Trajectory的参
  • ROS 如何用自己的电脑连接其他设备查看Rviz

    Rviz的使用在ROS开发中是很常见的东西 xff0c 有时候为了方便我们需要查看某台设备的一些数据 xff0c 但是又没有一些直观的连接工具例如向日葵之类的 这些工具是要基于屏幕的 xff0c 如果设备上没有屏幕是无法使用的 那在只有ss
  • 调试时正常,maven install 找不到符号

    找不到符号 很可能是引用的自己的库没有加载最新版 把所有库都clean gt install一下 或root项目下clean gt install
  • 【springboot】org.aspectj.lang.ProceedingJoinPoint获取返回类型、参数名称/值等

    1 参数值 span class token class name Object span span class token punctuation span span class token punctuation span args s
  • no opencv_java455 in java.library.path

    直接把 opencv build java x64下的文件opencv java455 dll复制到Java JDK安装的bin目录下就解决了这个问题
  • openssl pem 生成公钥和私钥及文件

    下载 xff1a http slproweb com products Win32OpenSSL html 首先得安装OpenSSL软件包openssl xff0c 安装了这个软件包之后 xff0c 我们可以做这些事情 xff1a o Cr
  • DebugDiag 2 收集Dump

    DebugDiag简介 Debug Diagnostic Tool DebugDiag 是微软提供的工具 xff0c 可以用来追踪windows平台下的程序崩溃 xff0c 卡死 xff0c 内存泄漏等一些疑难问题的原因 xff0c 按照问
  • Stream List 的排序

    1 list的正序 span class token class name List span span class token generics span class token punctuation lt span span clas
  • 嵌入式WebSocket的实现

    系统硬件采用STM32 43 DM9000AEP xff0c 具体实现步骤如下 xff0c 第一步建立TCP监听端口可以随意 xff0c 等待浏览器发出http请求 Chrome浏览器发出的请求 第二步建立握手 服务端需要解析最少4个头字段
  • spring boot 注册成 windows 服务

    1 windows系统下将 34 java jar 34 注册成 windows 服务 demo bat 64 echo off d span class token builtin class name cd span d span cl

随机推荐

  • Golang UI

    GUI库 Fyne 跨平台 xff0c 移动端 相对复杂 https github com fyne io fyne Walk 精于 windows https github com lxn walk
  • 解决golang编译提示dial tcp 172.217.160.113:443: connectex: A connection attempt failed

    废话不多说 xff0c 直接开讲 还多新手朋友在编译go的过程中是不是经常会遇到这样的报错 module Get https proxy golang org dial tcp 172 217 160 113 443 connectex A
  • 更新后报错

    更新后 xff0c 运行程序就报这个错 no required module provides package xxx go mod file not found in current directory or any parent dir
  • go: go.mod file not found in current directory or any parent directory; see ‘go help modules‘

    go go mod file not found in current directory or any parent directory see go help modules 此时还需要初始化Go moudle go mod init
  • vc++ 6.0bug C1853

    c documents and settingsstudent桌面musicplayermaindlg cpp 1 fatal error C1853 Debug MusicPlayer pch is not a precompiled h
  • 人工智能知识点汇总

    一 AI应用领域 AI目前主要的应用领域有3个方向 xff0c 包括 xff1a 计算机视觉 语音交互 自然语言处理 1 1 计算机视觉 xff08 CV xff09 计算机视觉是一门研究如何使机器 看 的科学 xff0c 就是指用摄影机和
  • Java17(291)之后 , 禁用了TLS1.1 , 使JDBC无法用SSL连接SqlServer怎么办,以下是解决办法

    修改java security文件 1 找到jre的java security文件 2 打开java security并搜索 jdk tls disabledAlgorithms 61 3 删掉TLSv1 TLSv1 1 4 保存 可以了
  • NumPy、Torch和Tensorflow 代码对比

    深度学习 在深入学习的基本单位上实施初级到高级操作 gt Excerpts 我习惯于为不同的问题创建新的深度学习架构 xff0c 但选择哪个框架 xff08 Keras Pytorch TensorFlow xff09 通常比较困难 由于其
  • 2023年 机器学习常用算法

    01 线性回归 线性回归 xff08 Linear Regression xff09 可能是最流行的机器学习算法 线性回归就是要找一条直线 xff0c 并且让这条直线尽可能地拟合散点图中的数据点 它试图通过将直线方程与该数据拟合来表示自变量
  • STM32上SPI+DMA实现大批量读取flash数据

    最近做项目需要使用SPI 43 DMA xff0c 为了做实验感受DMA传输数据块 xff0c 本人以SPI 43 DMA来读取flash中的数据 网上有很多例程是spi直接读取flash xff0c 无法提高性能 因为只是简单的实验SPI
  • stm32通用定时器1s延时实现LED闪烁

    stm32有很多定时器 xff0c 每种定时器的功能也不尽相同 xff0c 今天学习了如何用通用定时器实现1s延时 xff0c 使LED灯闪烁 xff0c 现总结如下 xff1a 步骤总结 xff1a 使能定时器时钟 gt 配置定时器结构体
  • JDK 中使用js调用java类、方法

    最近研究阅读这个APP 其主要功能就是通过一个个书源 从而实现移动端阅读的体验 比如说某些在线小说阅读网站 会加上相应的广告 从而影响用户阅读体验 于是阅读这个APP就是做了类似净化阅读体验 但是小说阅读网站千千万万 如果去适配每个小说阅读
  • Spring项目在tomcat启动时调用action

    1 实现ServletContextListener接口 添加 64 WebListener注解 2 按照示例写代码 xff1a 第一个是开启时 xff0c 第二个是销毁时
  • ubuntu16.04安装opencv3.4

    参考blog https blog csdn net u013066730 article details 79411767 直接进行 完全没问题 sudo apt get install build essential libgtk2 0
  • 使用switch-case语句输出成绩等级

    问题描述 xff1a 输入一个0 100范围内发分数 xff0c 在不同的等级范围内输出不同的值 xff0c 要求使用switch case控制 0 60 等级为E 60 70 等级为D 70 80 等级为C 80 90 等级为B 90 1
  • 输出图案(六)---输出空心矩形

    输入矩形的宽 xff0c 高 xff0c 输出该空心矩形 xff0c 用 来进行表示 参考代码1 xff1a span class hljs comment include lt stdio h gt span span class hlj
  • C语言中交换两个数的方法

    问题描述 xff1a 程序中有两个数a b 其中a 61 4 b 61 5 xff0c 现在希望交换两个数的值 xff0c 使得a 61 5 b 61 4 在这里我总结了一下目前我已经掌握的C语言中交换两个数的方法 xff0c 主要如下几种
  • 输出平行四边形图案(多种方案)

    问题描述 xff1a 使用 在控制台打印平行四边形 例如 xff1a 平行四边形中最长的一行输出的 是5个 xff0c 则平行四边为 xff1a span class hljs bullet span span class hljs emp
  • 自己实现strcat函数

    问题描述 xff1a 自己实现一个MyStrcat函数 xff0c 要和C语言库函数的strcat函数完成同样的功能 问题分析 xff1a 首先我们要了解一下strcat函数它到底做了什么事情 1 函数原型 char strcat char
  • 简易文件打包程序

    对指定目录下面的文件进行打包 简易解包程序参考博客另外一篇文章 xff1a http blog csdn net yi ming he article details 77689453 打包方式 xff1a 把目录下面的文件名 xff0c