精华内容
下载资源
问答
  • WINRAR压缩软件

    2019-01-21 14:07:03
    我们知道不能建立多卷解包是某种压缩软件的的一大缺陷,而它处理这种工作却是游刃有余,而且对解包文件还可加上密码加以保护。 实战:启动这款软件进入主界面,选好压缩对象后,选文件选单下的“密码”,输入...
  • 问题:以搜狗输入法的...(参考文章《 将exe和dll文件打包成单一的启动文件》使用的压缩软件是winrar) 1.选中所有的文件,鼠标右键单击,选择【添加到压缩文件(A)…】 2.填写压缩文件名(打包后生成exe文件的文...

    问题:以搜狗输入法的截图软件为例,如何将exe和dll文件打包成一个的exe可执行文件,即将该软件目录下的文件合并成一个可以独立运行的exe文件

    解决:通过压缩软件,本文我使用的软件是2345好压。(参考文章《 将exe和dll文件打包成单一的启动文件》使用的压缩软件是winrar)
    将exe和dll文件打包成一个exe文件
    1.选中所有的文件,鼠标右键单击,选择【添加到压缩文件(A)…】
    选择添加到压缩文件
    2.填写压缩文件名(打包后生成exe文件的文件名),文件扩展名需为exe,此时会自动勾选【创建自解压格式】,点击右边的【自解压选项】按钮
    (若没有出现该界面,是因为处于轻巧模式,点击右下角的切换至经典模式即可)
    填写压缩文件名
    3.在打开的【高级自解压选项】弹窗中,点击【解压】选项卡,在【解压后运行】中填写原所有文件中需要执行的exe文件名,若填写错误打包后运行程序会报错找不到文件。
    解压选项卡
    4.点击【模式】选项卡,勾选【解包到临时文件夹】,勾选【全部隐藏】
    作用:运行打包后的文件时,会将原来的exe和库文件地拷贝到一个临时文件夹,并且不会显示进度对话框。
    模式选项卡
    5.点击【更新】选项卡,勾选【解压并替换文件】,勾选【覆盖所有文件】
    作用:当多次运行打包后的exe可执行文件,系统重复解压你的文件到临时文件夹,并且不会询问你是否覆盖
    更新选项卡
    6.点击【图标】选项卡,在【从文件中加载自解压文件图标】处添加ico图标文件;或在【从文件中加载自解压文件会标】处添加BMP格式文件。

    PS:我在网上下载的图标是白色背景的png图片,于是先用免费在线抠图去掉了背景,然后用图标格式在线转换将png转为ico文件
    在线抠图:https://www.remove.bg
    png转ico:https://www.easyicon.net/covert
    图标选项卡
    7.点击确定,会在当前目录下生成一个exe可执行文件,文件名为步骤2填写的文件名。

    展开全文
  • Python代码实现压缩软件

    千次阅读 多人点赞 2019-12-29 22:44:10
    我在想能不能用Python自己实现一个压缩软件,这样自己用的也方便,也不怕有什么广告了,我们的故事便从这里开始…… 一、相关库简介 (1)zipfile库 首先我想到了Python中有一个实现解压缩的很方便的库——zipfile库...

    写在前面的话

           诗经有云:五月斯螽动股,六月莎鸡振羽,七月在野,八月在宇,九月在户,十月蟋蟀入我床下。十一月有点凉,十二月被窝到不了的地方都是远方。这句话的意思就是:五月蚱蜢弹腿跳,六月纺织娘振翅,七月蟋蟀在田野,八月来到屋檐下,九月蟋蟀进门口,十月钻进我床下。十一月天气有点凉,十二月被窝到不了的地方都是远方。

           既然天气这么冷,不想去远方,不如搞点事情吧~ 前几天因为工作关系,需要远程其他地方的电脑,为了方便,下载了某远程工具,结果自动安装上了一堆的流氓软件,其中就有一个压缩软件,天天推送一些不知所云的广告,让我花费了很大的力气才彻底清除。我在想能不能用Python自己实现一个压缩软件,这样自己用的也方便,也不怕有什么广告了,我们的故事便从这里开始……


    一、相关库简介

           (1)zipfile库

           首先我想到了Python中有一个实现解压缩的很方便的库——zipfile库。zipfile用来做zip格式编码的压缩和解压缩,由于是很常见的zip格式,所以这个模块使用频率也是比较高。它有两个非常重要的class,分别是ZipFile和ZipInfo, 在绝大多数的情况下,只需要使用这两个class就可以。ZipFile是主要的类,用来创建和读取zip文件;ZipInfo是存储的zip文件的每个文件的信息的。

           (2)os库

           Python的os模块提供了简单方便的方法来使用操作系统的一些功能。就是说通过os库可以使用python执行一些常见的操作系统的功能,比如切换目录,增删文件,设置环境变量,运行shell 命令等等。以下是os库常用的部分:

    os.sep:可以取代操作系统特定的路径分隔符。
    os.name:字符串指示你正在使用的平台。比如对于Windows,它是'nt',而对于Linux/Unix用户,它是'posix'。
    os.getcwd():函数得到当前工作目录,即当前Python脚本工作的目录路径。
    os.getenv():获取一个环境变量,如果没有返回none。
    os.link():方法用于创建硬链接。
    os.mkdir():方法用于以数字权限模式创建目录。
    os.listdir(path):返回指定目录下的所有文件和目录名。
    os.remove(path):函数用来删除一个文件。如果指定的路径是一个目录,将抛出OSError,在Unix,Windows中有效。
    os.rmdir(path):方法用于删除指定路径的目录。仅当这文件夹是空的才可以,否则,抛出OSError。
    os.system(command):函数用来运行shell命令。
    os.linesep:字符串给出当前平台使用的行终止符。
    os.curdir:返回当前目录('.')。
    os.chdir(dirname):改变工作目录到dirname。
    
    os.path常用方法:
    os.path.isfile(path)和os.path.isdir(path)函数:分别检验给出的路径是一个文件还是目录,绝对路径。
    os.path.existe():函数用来检验给出的路径是否真地存在。
    os.path.getsize(name):获得文件大小。
    os.path.abspath(name):获得绝对路径。
    os.path.normpath(path):规范path字符串形式。
    os.path.split(path):将path分割成目录和文件名二元组返回。
    os.path.splitext():分离文件名与扩展名。
    os.path.join(path,name):连接目录与文件名或目录;使用“\”连接。
    os.path.basename(path):返回文件名。
    os.path.dirname(path):返回文件路径​。

           (3)Tkinter组件

           Tkinter提供的各种控件如下图所示:

           Tkinter组件的标准属性(所有控件均有的属性)如下所示:

           Tkinter控件有特定的几何状态管理方法,管理整个控件区域组织,以下是Tkinter公开的几何管理类:包、网格、位置。

    二、相关方法编写

           1、首先需要有选择文件的功能,例如:选择需要压缩的文件和选择需要解压缩的文件,方法如下:

    def choose_compress_file():
        '''
        选择需要压缩的文件
        :return:
        '''
        compress_file_path_name.set(askdirectory())
    
    def choose_uncompress_file():
        '''
        选择需要解压的文件
        :return:
        '''
        uncompress_file_path = askopenfilename()
        uncompress_file_path.replace("/", "\\\\")  # 字符转义
        uncompress_file_path_name.set(uncompress_file_path)

           2、选择文件的功能有了,就需要思考一个问题:解压的文件需要有一个解压的目录,所以此处还需要一个解压到某个目录的方法,如下:

    def choose_uncompress_dir():
        '''
        选择解压到的目录
        :return:
        '''
        uncompress_file_terminal_path_name.set(askdirectory())

           3、然后,压缩、解压成功或者失败后是不是得需要设置一些信息进行以下提示,这里又需要压缩或解压成功、失败的提示信息方法,如下所示:

    def compress_file_success_message():
        '''
        压缩文件成功后,弹出信息框
        :return:
        '''
        tkinter.messagebox.askokcancel(title='success', message='压缩成功!')
    
    def uncompress_file_success_message():
        '''
        解压文件成功后,弹出信息框
        :return:
        '''
        tkinter.messagebox.askokcancel(title='success', message='解压成功!')
    
    def uncompress_file_failure_message():
        '''
        解压失败弹出框
        :return:
        '''
        tkinter.messagebox.askokcancel(title='failed', message='这不是zip压缩文件!')

           4、这些基本方法设置完之后,就到了核心模块了——压缩和解压缩的方法。

    def compress_file():
        '''
        压缩文件
        :return:
        '''
        # 给压缩文件加上.zip
        compress_file_name = compress_file_path_name.get() + '.zip'
    
        # 写入
        zip = zipfile.ZipFile(compress_file_name, 'w', zipfile.ZIP_DEFLATED)
    
        # 遍历目录路径、目录名、文件名
        for dirpath, dirnames, filenames in os.walk(compress_file_path_name.get()):
            fpath = dirpath.replace(compress_file_path_name.get(), '')
            fpath = fpath and fpath + os.sep or ''
    
            # 迭代文件名
            for filename in filenames:
                zip.write(os.path.join(dirpath, filename), fpath + filename)  # 写入
            zip.close()
    
            # 压缩成功,弹出信息框
            compress_file_success_message()
    
    def upcompress_file():
        '''
        解压缩文件
        :return:
        '''
        # 判断是否为压缩文件,以文件后缀是否为.zip为判断依据
        is_true = zipfile.is_zipfile(uncompress_file_path_name.get())
    
        if is_true:
            # 读取压缩文件
            unzip = zipfile.ZipFile(uncompress_file_path_name.get(), 'r')
            # 遍历文件
            for file in unzip.namelist():
                # 输出文件
                unzip.extract(file, uncompress_file_terminal_path_name.get())
    
            # 解压成功,弹出信息框
            uncompress_file_success_message()
        else:
            # 解压失败,弹出信息框
            uncompress_file_failure_message()

           5、当然还得需要咱们的图形用户界面,所以此处还是设置一个图形用户界面的方法,如下:

    def graphical_user_interface():
        '''
        图形用户界面
        :return:
        '''
        # label:ow代表label是放在第几行,column是放在第几列
        Label(root, text='压缩文件路径:').grid(row=0, column=0)
    
        # entry:获取输入
        Entry(root, textvariable=compress_file_path_name).grid(row=0, column=1)
    
        # 操作按钮
        Button(root, text='选择压缩文件', command=choose_compress_file).grid(row=0, column=2)
    
        # label标签
        Label(root, text='解压文件路径:').grid(row=1, column=0)
    
        # 获取输入
        Entry(root, textvariable=uncompress_file_path_name).grid(row=1, column=1)
    
        # 操作按钮
        Button(root, text='选择解压文件', command=choose_uncompress_file).grid(row=1, column=2)
    
        # label标签
        Label(root, text='解压到:').grid(row=2, column=0)
    
        # 获取输入
        Entry(root, textvariable=uncompress_file_terminal_path_name).grid(row=2, column=1)
    
        # 操作按钮
        Button(root, text='选择解压路径', command=choose_uncompress_dir).grid(row=2, column=2)
    
        # 操作按钮
        Button(root, text='点击压缩', command=compress_file).grid(row=3, column=0)
    
        # 操作按钮
        Button(root, text='点击解压', command=upcompress_file).grid(row=3, column=2)
    
        # 操作按钮
        Button(root, text='退出', command=root.quit).grid(row=4, column=1)
    
        # 显示操作界面
        root.mainloop()

           至此,所需要的所有方法均已经设置完毕。是时候进行测试了~

    三、测试

    if __name__ == '__main__':
        # 初始化,并设置文件名称
        root = Tk(className='轻压-极简版')
        # 设置标题,与root = Tk(className='轻压-极简版')有异曲同工之妙
        # root.title('轻压')
    
        # 设置压缩屏幕大小
        # root.geometry('1000x150')
    
        # 设置压缩图标
        # root.iconbitmap(default='xzw.ico')
    
        # 显示需要压缩的文件路径名
        compress_file_path_name = StringVar()
    
        # 显示需要解压的文件路径名
        uncompress_file_path_name = StringVar()
    
        # 显示文件想要解压到的路径名
        uncompress_file_terminal_path_name = StringVar()
    
        # 函数调用,显示图形用户界面
        graphical_user_interface()

           测试结果如下:

           点击相应的按钮可以进行压缩和解压缩的操作~ 这样又暴露出了一个问题,如果别人想用这个软件,但是又不具备Python环境,这样该怎么办呢?于是便有了一下打包成.exe文件的操作。

    四、打包成.exe文件

           可以使用pyinstaller命令打包对应的.py文件。pyinstaller命令常用的参数如下所示:

    -F, --onefile Py代码只有一个文件
    -D, --onedir Py代码放在一个目录中(默认是这个)
    -K, --tk 包含TCL/TK
    -d, --debug 生成debug模式的exe文件
    -w, --windowed, --noconsole 窗体exe文件(Windows Only)
    -c, --nowindowed, --console 控制台exe文件(Windows Only)
    -X, --upx 使用upx压缩exe文件
    -o DIR, --out=DIR 设置spec文件输出的目录,默认在PyInstaller同目录
    --icon=<FILE.ICO> 加入图标(Windows Only)
    -v FILE, --version=FILE 加入版本信息文件

           这里,我们使用如下命令进行打包:

    pyinstaller -w -F -i compressed_software/favicon.ico compressed_software/lkys.py

           在控制台出现如下情况说明打包成功:

            打包后的.exe文件会出现在项目的dist目录下,将其拷贝出来后,如下所示:

           点击运行,如下所示,说明成功:

    五、一些并不怎么愉快的事情

           打包成.exe文件后,在运行时发生了一些并不怎么愉快的事情,首先运行的时候会报一个运行脚本发生错误的问题,如下所示:

           因为打包时使用了-w的参数,所以运行.exe文件并没有启动Windows窗口,故而再次打包。发现报了如下两个错误:

           1、_tkinter.TclError: bitmap "xzw.ico" not defined

           2、PermissionError: [Errno 13] Permission denied: 'picture.ico'

           相关错误的解决办法,有兴趣的可以点击错误链接查看。

    六、源码

           源码已经同步至GitHub,有兴趣的同志可以点此进行查看~ 因为时间关系,此次压缩软件图形用户界面做的比较简陋,只能算是极简版,往后会慢慢的更新优化用户界面,相关代码也会在GitHub上实时更新,本篇文章到此结束,谢谢大家。

     

           你们在此过程中遇到了什么问题,欢迎留言,让我看看你们都遇到了哪些问题。

    展开全文
  • 打造前端 Deepin Linux 工作环境——GUI图形压缩软件 PeaZip 的安装与设置说实话,谁不喜欢简单明了的图形化的软件呢。但是在 linux 和 mac 上关于压缩软件的图形化的实在是不多,并且 mac 上的还收费还不好用。为此...

    打造前端 Deepin Linux 工作环境——GUI图形压缩软件 PeaZip 的安装与设置

    说实话,谁不喜欢简单明了的图形化的软件呢。但是在 linuxmac 上关于压缩软件的图形化的实在是不多,并且 mac 上的还收费还不好用。为此,我才用命令行的工具 atool 的。

    今天我找到一个好用的图形化的压缩软件 PeaZip 这个软件。跨平台,开源,功能全面,支持的格式也多。因此,推荐给大家使用。

    安装 PeaZip 压缩软件

    打开终端,输入下面的命令进行搜索

    apt-cache search peazip

    看是否包含这个安装包。 deepin 我这边看到是有这个包的。所以执行下面的命令安装:

    sudo apt-get install peazip -y

    这个软件依赖的包还比较多,不过没关系,一会儿就安装完成了。

    打开软件

    PeaZip

    好,我们可以看到这个软件和我们在 windows 上接触的 winrar 是差不多的。但是默认是英文。所以我们需要设置一下:

    设置 PeaZip 压缩软件

    PeaZip Menu

    首先,我们点击菜单栏的 Options 然后点击 Localization,会弹出如下方的选择本地语言配置选框,我们选择 chs.txt 然后点击 打开 就设置好了。

    PeaZip Chs

    设置语言之后,软件会自动重启,重启之后,就可以看到已经全部变成中文了。应该说,还是感到很亲切的。

    PeaZip cinese

    peazip 的官方网址是 http://www.peazip.org/peazip-linux.html

    本文由FungLeo原创,允许转载,但转载必须附注首发链接。谢谢。

    展开全文
  • 一个简单的压缩软件,利用哈夫曼思想,构造哈夫曼编码,实现对文件的二进制压缩,以及解压,再利用MFC制作可视化操作界面,美化软件又简化文件操作。(各个步骤有解释可看) 软件主页面先看看 哈夫曼树结构 构造...

    前言

    一个简单的压缩软件,利用哈夫曼思想,构造哈夫曼编码,实现对文件的二进制压缩,以及解压,再利用MFC制作可视化操作界面,美化软件又简化文件操作。(各个步骤有解释可看)

    软件主页面先看看

    在这里插入图片描述

    哈夫曼树结构

    构造哈夫曼树存储结构:w权重即每个字节出现频度,byte结点数据即每个字节的ASCII码,fa双亲结点下标,le左孩子下标,ri右孩子下标,从下往上开始构建哈夫曼树。
    根据已构造完成的哈夫曼树,从上往下开始构造每个结点的哈夫曼编码字符串,从根节点出发,如果下一个节点是其双亲的右孩子结点则在编码后接1,如果是左孩子结点则在编码后接0.存放哈夫曼树信息用到的是Huff_arr数组。

    struct HaffNode {
    	unsigned char byte;//为节点所代表的字符(ASCII码表对应的字符)
    	long long w;//此节点代表字符的出现频度
    	int num, fa, le, ri, code_len;//分别为节点在Huff_arr数组下标,双亲节点在Huff_arr数组下标,
        左子树下标,右子树下标,对应哈夫曼编码长度
    	char code[256];//哈夫曼编码
    	bool operator < (HaffNode x) const {
    		return w > x.w;
    	}
    }Huff_arr[512]
    

    步骤

    ①读取文件操作(包括初始化)

    1、 读原文件,统计字节频度,定义Huffman树和Huffman编码的储存结构
    读取文件,新建一个二进制文件用于存放统计数据,用while语句逐个读取源文件每一个字节,在每次读取的时候分别统计出现次数(权值)w和源文件长度file_length,直至文件结束。
    2、 原文件字节频度统计
    对字节频度排序,利用sort函数对Huff_arr[0]~ Huff_arr[520]的元素以weight为排序关键字进行降序排序。

    void initpow(char *cp_inname) {
    	unsigned char ch;
    	CString str;
    	FILE *ifp = fopen(cp_inname, "rb");
    	if (ifp == NULL) {
    		MessageBox(NULL, _T("该文件已存在,请重新输入"), _T("错误"), MB_ICONEXCLAMATION);
    		return;
    	}
    	file_len = 0, bytes_cnt = 0;
    	fread(&ch, 1, 1, ifp);
    	while (!feof(ifp)) {
    		Huff_arr[ch].w++, file_len++;
    		fread(&ch, 1, 1, ifp);
    	}
    	fclose(ifp);
    	for (int i = 0; i < 256; i++)
    		if (Huff_arr[i].w > 0)
    			bytes_cnt++;
    	sort(Huff_arr, Huff_arr + 511);
    }
    
    

    ②建树

    利用优先队列(priority_queue QUEUE;),每次取队头元素(权值第一小)First节点,出队后再取队头元素S(权值第二小)econd,然后将两棵子树合并为一棵子树,权值相加,并将新子树的根节点顺序存放到数组huff_arr ,再把新子树的根节点放进队列再次循环步骤,直到队列的个数为1为止。

    void createhafftree() {
    	priority_queue<HaffNode> QUEUE;
    	HaffNode First, Second, Sum;
    	int tot = bytes_cnt;
    	while (QUEUE.size())QUEUE.pop();
    	for (int i = 0; i < bytes_cnt; i++)
    		Huff_arr[i].num = i, QUEUE.push(Huff_arr[i]);
    	while (QUEUE.size() > 1) {
    		First = QUEUE.top(), QUEUE.pop();
    		Second = QUEUE.top(), QUEUE.pop();
    		Sum.num = tot, Sum.w = First.w + Second.w;
    		Sum.fa = -1, Sum.le = First.num, Sum.ri = Second.num;
    		strcpy(Sum.code, "");
    		Huff_arr[First.num].fa = Sum.num, Huff_arr[Second.num].fa = Sum.num;
    		Huff_arr[tot++] = Sum;
    		QUEUE.push(Sum);
    	}
    

    ③构造哈夫曼编码

    根据已构造完成的哈夫曼树,从上往下开始构造每个结点的哈夫曼编码字符串,从根节点出发,如果下一个节点是其双亲的右孩子结点则在编码后接1,如果是左孩子结点则在编码后接0.哈夫曼编码树的左分支代表 0,右分支代表 1,则从根结点到每个叶子结点所经过的路径组成的 0 和 1 的序列便成为该叶子结点对应字符的编码。

    void createhaffcode() {
    	int tot = bytes_cnt * 2 - 1;
    	Huff_arr[tot - 1].code[0] = '\0';
    	for (int i = tot - 2; i >= 0; i--) {
    		strcpy(Huff_arr[i].code, Huff_arr[Huff_arr[i].fa].code);
    		if (Huff_arr[Huff_arr[i].fa].ri == i)
    			strcat(Huff_arr[i].code, "1");
    		else
    			strcat(Huff_arr[i].code, "0");
    		Huff_arr[i].code_len = strlen(Huff_arr[i].code);
    	}
    }
    

    ④生成压缩文件

    生成压缩码:先找出根节点的位置,然后从根节点一直往下进行编码,根据左孩子置为0,右孩子置为1这个规则一直往下编码,根据编码继承,可以直接在父节点的编码后面置0或1即可。
    根据编码写入文件:得到哈夫曼编码后先将缓冲区置为空,然后按照每8位为一个字节,将二进制转为十进制进行写入文件,如果最后缓冲区还有元素,则在后面补8个0,然后再整除8,变为8位元素。

    ofp = fopen(cp_outname, "wb");
    	if (ofp == NULL) {
    		MessageBox(NULL, _T("未能成功打开文件"), _T("错误"), MB_ICONEXCLAMATION);
    		return;
    	}
    	fprintf(ofp, "%d,%s,%lld,%d,", strlen(file_extension), file_extension, file_len, bytes_cnt);
    	for (int i = 0; i < bytes_cnt; i++)
    		fprintf(ofp, "%c,%lld,", Huff_arr[i].byte, Huff_arr[i].w);
    	ifp = fopen(cp_inname, "rb");
    	if (ifp == NULL) {
    		MessageBox(NULL, _T("打开文件失败"), _T("错误"), MB_ICONEXCLAMATION);
    		return;
    	}
    	strcpy(buff, "");
    	ch = fgetc(ifp);
    	while (!feof(ifp)) {
    		if (Buffmax - strlen(buff) > 256) {
    			for (int i = 0; i < bytes_cnt; i++) {
    				if (Huff_arr[i].byte == ch) {
    					strcat(buff, Huff_arr[i].code), ch = fgetc(ifp);
    					break;
    				}
    			}
    		}
    		else {
    			flushBuffer(ofp);
    		}
    	}
    	flushBuffer(ofp);
    	if (strlen(buff) > 0) {
    		strcat(buff, "00000000");
    		flushBuffer(ofp);
    		strcpy(buff, "");
    	}
    	fclose(ofp);
    	fclose(ifp);
    

    注意:

    生成压缩文件一定要在文件里面记录相应的扩展名以及哈夫曼树的重要存储结构,即源文件对应的字符和字符频度,在将哈夫曼编码每八位转成一个十进制值对应的字符时,有可能哈夫曼编码不是8的整数倍,需要在哈夫曼编码最后面补充8个0,多余的哈夫曼编码便可借0补位,以此避免二进制文件写入错误。

    为了读文件快点,利用缓冲区

    void flushBuffer(FILE * fp) { // 把缓冲区中,尽可能多的字节,写入文件中 
    	strcpy(bufstr, "");
    	unsigned char temp = 0;
    	int byte_data_num = strlen(buff) / 8, i;
    	for (i = 0; i < byte_data_num; i++) {
    		temp = 0;
    		for (int j = 0; j < 8; j++) {
    			if (buff[i * 8 + j] == '1')
    				temp += pow(2, 7 - j);
    		}
    		bufstr[i] = temp;
    	}
    	bufstr[i] = '\0';
    	fwrite(bufstr, 1, byte_data_num, fp);
    	strcpy(buff, buff + byte_data_num * 8);
    }
    

    ⑤解压文件

    1、 读压缩文件的头部
    (1) 读源文件的扩展名长度,把扩展名存储以便生成解压文件可用来定义文件类型,读入源文件的总字节数,读入源文件中被编码的字节总数
    (2) 根据(1)中读入的被编码的字节总数,依此读取字符和字符频度,初始化哈夫曼树存储结构,构造哈夫曼树
    (3) 读取哈夫曼总编码生成的二进制数据。
    2、 对压缩文件进行解压
    (1) 读取分哈夫曼总编码生成的二进制数据分批次装满缓冲区,写入文件
    (2) 缓冲区内的下一位,若是0,则转向左孩子,若是1,则转向右孩子
    (3) 找出叶子节点,并把该字节写入解压文件中,即是还原每个节点对应的哈夫曼编码,找出每个哈夫曼编码对应的节点,将节点对应的ASCII码的字符写入生成文件

    ifp = fopen(dcp_inname, "rb");
    	if (ifp == NULL) {
    		MessageBox(NULL, _T("此压缩文件不存在或被占用!"), _T("错误"), MB_ICONEXCLAMATION); 
    		return;
    	}
    	strcpy(dat_file_extension, "");
    	fscanf(ifp, "%d,", &sufname_len);
    	fread(&dat_file_extension, sufname_len, 1, ifp);
    	fscanf(ifp, ",%lld,%d,", &file_len, &bytes_cnt);
    	for (int i = 0; i < bytes_cnt; i++)
    		fscanf(ifp, "%c,%lld,", &Huff_arr[i].byte, &Huff_arr[i].w);
    
    	//构造哈弗曼树并输出
    	createhafftree();
    	/*printhafftree();*/
    
    	//生成文件绝对路径
    	strcat(dcp_outname, ".");
    	strcat(dcp_outname, dat_file_extension);
    	//解压
    	ofp = fopen(dcp_outname, "wb");
    	if (ofp == NULL) {
    		MessageBox(NULL, _T("解压文件生成失败!"), _T("错误"), MB_ICONEXCLAMATION);
    		return;
    	}
    	strcpy(buff, ""), strcpy(block, "");
    	fread(buff, 1, Buffmax - 1, ifp);
    	root = bytes_cnt * 2 - 2, trcur = root;
    	while (dfile_len < file_len) {
    		if (blcur >= Blockmax - 1) {
    			fwrite(block, 1, blcur, ofp);
    			blcur = 0;
    		}
    		if (Huff_arr[trcur].le == -1) {
    			block[blcur++] = Huff_arr[trcur].byte, block[blcur] = '\0';
    			trcur = root, dfile_len++;
    			if (blcur == 510) {
    				int xxdx = 1;
    				xxdx++;
    			}
    		}
    		else {
    			if ((buff[bucur] >> (7 - bycur)) & 1)
    				trcur = Huff_arr[trcur].ri;
    			else
    				trcur = Huff_arr[trcur].le;
    			if (bycur < 7)
    				bycur++;
    			else {
    				bycur = 0, bucur++;
    				if (bucur >= Buffmax - 1)
    					fread(buff, 1, Buffmax - 1, ifp), bucur = 0;
    			}
    		}
    	}
    	fwrite(block, 1, blcur, ofp);
    	fclose(ifp), fclose(ofp);
    

    MFC主要三个按钮响应事件代码

    void CHuffmanDlg::OnBnClickedButton1() //压缩文件按钮对应的事件
    {
    	// TODO: 在此添加控件通知处理程序代码
    	CString strFile = _T("");
    	CString str3;
    	str3.Format(_T("请选择所需要进行压缩的文件:"));
    	if (MessageBox(str3, _T("提示"), MB_ICONEXCLAMATION | MB_OKCANCEL) == IDCANCEL) {
    		return;
    	}
    	else {
    		CFileDialog    dlgFile(TRUE, NULL, NULL, OFN_HIDEREADONLY, _T("Describe Files All Files (*.*)|*.*||"), NULL);
    
    		if (dlgFile.DoModal())
    		{
    			strFile = dlgFile.GetPathName();
    		}
    	}
    	if (strFile == "")
    		return;
    	CString str4;
    	Edit_text YS;
    	str4.Format(_T("请选择是否为生成文件重新命名:"));
    	named_ok = false;
    	//是否进行对生成文件的命名
    	if (MessageBox(str4, _T("选择"), MB_ICONQUESTION | MB_YESNO) == IDNO) {
    		named_ok = false;
    	}
    	else {
    		named_ok = true;
    		YS.DoModal();
    	}
    	//对文件名进行修改
    	USES_CONVERSION;
    	char * inFileName = T2A(strFile);
    	int ok = 0;
    	int pos1 = 0,pos2;
    	strcpy(cp_file_name, "");
    	strcpy(file_extension, "");
    	char temp[MAX_PATH] = "";
    	for (int i = strlen(inFileName) - 1; i >= 0; i--) {
    		if (inFileName[i] == '\\') {
    			break;
    		}
    		if (ok == 1) {
    			temp[pos1++] = inFileName[i];
    		}
    		if (inFileName[i] == '.') {
    			pos2 = i + 1;
    			ok = 1;
    		}
    	}
    	int tot = 0;
    	for (int i = pos2; i < strlen(inFileName); i++)
    		file_extension[tot++] = inFileName[i];
    	int num = 0;
    	for (int i = pos1 - 1; i >= 0; i--) {
    		cp_file_name[num++] = temp[i];
    	}
    	strcat(cp_file_name, ".dat");
    	CString NAME= YS.FILE_NAME + ".dat";//文本框传来的信息
    	if (!named_ok)
    		NAME= CA2CT(cp_file_name);
    	char szPath[MAX_PATH];//存放选择的目录路径
    	CString str1, str2, FileName;
    	CTime m_time;
    	ZeroMemory(szPath, sizeof(szPath));
    	BROWSEINFO bi;
    	bi.hwndOwner = m_hWnd;
    	bi.pidlRoot = NULL;
    	bi.pszDisplayName = (LPWSTR)szPath;
    	bi.lpszTitle = _T("请选择生成文件的目录:");
    	bi.ulFlags = BIF_BROWSEINCLUDEFILES | BIF_NEWDIALOGSTYLE;
    	bi.lpfn = NULL;
    	bi.lParam = 0;
    	bi.iImage = 0;
    	LPITEMIDLIST lp = SHBrowseForFolder(&bi);
    	FileName = m_time.Format(NAME); 
    	SHGetPathFromIDList(lp, (LPWSTR)szPath);
    	str2.Format(_T("%s"), szPath);
    	CString filePath = str2 + "\\" + FileName;//路径+文件名
    	if (lp && SHGetPathFromIDList(lp, (LPWSTR)szPath))
    	{
    		str1.Format(_T("选择生成文件的路径为: %s"), szPath);
    		if (MessageBox(str1, _T("路径"), MB_ICONEXCLAMATION | MB_OKCANCEL) == IDCANCEL) {
    			return;
    		}
    		else {
    			USES_CONVERSION;
    			//函数T2A和W2A均支持ATL和MFC中的字符
    			char * outFileName = T2A(filePath);
    			clock_t  clockBegin, clockEnd;
    			clockBegin = clock();
    			CFile cfile;
    			DOUBLE size1, size2;
    			if (cfile.Open(strFile, CFile::modeRead))
    			{
    				size1 = cfile.GetLength();
    			}
    			cfile.Close();
    			compressFile(inFileName, outFileName);
    			clockEnd = clock();
    			DOUBLE TIME = (clockEnd - clockBegin)/( CLOCKS_PER_SEC);
    			if (cfile.Open(filePath, CFile::modeRead))
    			{
    				size2 = cfile.GetLength();
    			}
    			cfile.Close();	
    			UpdateData(FALSE);
    			CString TIMESTR;
    			size1 /= 1024;
    			size2 /= 1024;
    			DOUBLE YSL = size2/ size1 * 100;
    			char s = '%';
    			TIMESTR.Format(_T("压缩文件耗时为:%.2lfs\n起始文件大小为:%.2lfKB\n压缩文件大小为:%.2lfKB\n文件的压缩率为:%.2lf%c"), TIME,size1, size2,YSL,s);
    			MessageBox(TIMESTR, _T("压缩成功"));
    		}
    	}
    	else
    	{
    		AfxMessageBox(_T("无效的目录,请重新选择"));
    		return;
    	}
    }
    
    
    void CHuffmanDlg::OnBnClickedButton2()//解压文件按钮对应的事件
    {
    	// TODO: 在此添加控件通知处理程序代码
    	CString strFile = _T("");
    	CString str3;
    	str3.Format(_T("请选择所需要进行解压的文件:"));
    	if (MessageBox(str3, _T("提示"), MB_ICONEXCLAMATION | MB_OKCANCEL) == IDCANCEL) {
    		return;
    	}
    	else {
    		CFileDialog    dlgFile(TRUE, NULL, NULL, OFN_HIDEREADONLY, _T("Describe Files All Files (*.*)|*.*||"), NULL);
    
    		if (dlgFile.DoModal())
    		{
    			strFile = dlgFile.GetPathName();
    		}
    	}
    	if (strFile == "")
    		return;
    	CString str4;
    	JIEYA_FILENAME JY;
    	str4.Format(_T("请选择是否为生成文件重新命名:"));
    	named_ok = false;
    	if (MessageBox(str4, _T("选择"), MB_ICONQUESTION | MB_YESNO) == IDNO) {
    		named_ok = false;
    	}
    	else {
    		named_ok = true;
    		JY.DoModal();
    	}
    	//对文件名进行修改
    	USES_CONVERSION;
    	char * inFileName = T2A(strFile);
    	int ok = 0;
    	int pos = 0;
    	strcpy(dcp_file_name, "");
    	char temp[MAX_PATH] = "";
    	for (int i = strlen(inFileName) - 1; i >= 0; i--) {
    		if (inFileName[i] == '\\') {
    			break;
    		}
    		if (ok == 1) {
    			temp[pos++] = inFileName[i];
    		}
    		if (inFileName[i] == '.') {
    			ok = 1;
    		}
    	}
    	int num = 0;
    	for (int i = pos - 1; i >= 0; i--) {
    		dcp_file_name[num++] = temp[i];
    	}
    	CString NAME = JY.TEXT_NAME;//文本框传来的信息
    	if (!named_ok)
    		NAME = CA2CT(dcp_file_name);
    	char szPath[MAX_PATH];//存放选择的目录路径
    	CString str1, str2, FileName;
    	CTime m_time;
    	ZeroMemory(szPath, sizeof(szPath));
    	BROWSEINFO bi;
    	bi.hwndOwner = m_hWnd;
    	bi.pidlRoot = NULL;
    	bi.pszDisplayName = (LPWSTR)szPath;
    	bi.lpszTitle = _T("请选择生成文件的目录:");
    	bi.ulFlags = BIF_BROWSEINCLUDEFILES | BIF_NEWDIALOGSTYLE;
    	bi.lpfn = NULL;
    	bi.lParam = 0;
    	bi.iImage = 0;
    	LPITEMIDLIST lp = SHBrowseForFolder(&bi);
    	FileName = m_time.Format(NAME); 
    	SHGetPathFromIDList(lp, (LPWSTR)szPath);
    	str2.Format(_T("%s"), szPath);
    	CString filePath = str2 + "\\" + FileName;//路径+文件名无扩展名
    	if (lp && SHGetPathFromIDList(lp, (LPWSTR)szPath))
    	{
    		str1.Format(_T("选择生成文件的路径为: %s"), szPath);
    		if (MessageBox(str1, _T("路径"), MB_ICONEXCLAMATION | MB_OKCANCEL) == IDCANCEL) {
    			return;
    		}
    		else {
    			USES_CONVERSION;
    			char * outFileName = T2A(filePath);
    			clock_t  clock1, clock2;
    			clock1 = clock();
    			deCompressFile(inFileName, outFileName);
    			clock2 = clock();
    			DOUBLE TIME = (clock2 - clock1)/ (CLOCKS_PER_SEC);
    			CString TIMESTR;
    			UpdateData(FALSE);
    			TIMESTR.Format(_T("\t解压成功!!!\t\n\t解压文件耗时为:%.2lfs\t"), TIME);
    			MessageBox(TIMESTR, _T("信息提示"));
    		}
    	}
    	else
    	{
    		AfxMessageBox(_T("无效的目录,请重新选择"));
    		return;
    	}
    }
    void CHuffmanDlg::OnBnClickedButton3()//退出按钮对应的事件
    {
    	// TODO: 在此添加控件通知处理程序代码
    	CString str3;
    	str3.Format(_T("是否确定要退出程序?"));
    	if (MessageBox(str3, _T("提醒"), MB_ICONEXCLAMATION | MB_OKCANCEL) == IDCANCEL) {
    		return;
    	}
    	else {
    		PostQuitMessage(0);
    	}
    }
    

    最后操作界面演示

    启动界面

    启动界面

    ①压缩文件

    (1)选择所要压缩的文件
    2
    (2)可为生成的压缩文件命名,并选择生成文件目录
    3
    4
    (3)压缩完成后,会显示:压缩耗时,起始文件大小,压缩文件大小,文件压缩率。
    在这里插入图片描述

    ②解压文件

    (1)选择所要解缩的文件
    6
    (2)可为生成的解压文件命名,并选择生成文件目录
    7
    9
    (3)解压完成后,会显示解压时间

    8

    最后的最后完整包

    由于利用了MFC 有一堆MFC的头文件和源文件,所以就不可能把所有代码贴上来了,制作了一个完整的压缩文件包可以供下载。
    在这里插入图片描述
    图中①是exe文件打开就可以运行,图中②是程序所有的文件,③可以用VS打开来,里面就是主要的代码。
    打开后,主要的核心代码在这个CPP里面
    在这里插入图片描述

    最后放上 完整文件包完整文件包ZIP下载地址

    展开全文
  • Linux开机启动程序详解 我们假设大家已经熟悉其它操作系统的引导过程,了解硬件的自检引导步骤,就只从Linux操作系统的引导加载程序(对个人电脑而言通常是LILO)开始,介绍Linux开机引导的步骤。 加载内核 ...
  • 1.本程序需要ROOT权限! 2.本程序插入小视频后,请启动微信,然后在14天内录制的小视频列表可找到视频文件,可以进行转发给好友或朋友圈等操作。...3.该版本支持自动压缩转码,不用再用其他工具压缩
  • 3D视频的引火式风靡,点云压缩才是幕后老大?
  • 有时候我们会启动一些使用解压缩安装的软件,这些软件在win里并没有记录,无法从第三方软件或者是任务管理器中启动软件,这就需要我们手动写一个脚本,实现开机时启动软件 需要使用: windows自带的任务计划程序 bat...
  •  ubuntu下桌面配置文件(*.desktop)存放路径为 /usr/share/applications ,该文件夹下存在的软件自然可以直接复制到桌面和加入启动器,但有些自己安装的软件(如解压缩包的软件)没有自动生成桌面配置文件,自然不...
  • 首先说明一下本文的需求:利用Windows自带的API、DLL或命令行参数等任何手段,解压一个标准的zip压缩文件,并且不借助任何第三方程序。 一、前言——徒劳的探索 为什么会提出这种需求呢?因为我近期在编程中,...
  • 软件安装:装机软件关于电脑装机必须的软件,比如windows office系列办公软件、网页浏览器、杀毒软件、安全防护软件、刻录软件、压缩软件、下载工具、多媒体播放软件、多媒体编辑软件、输入法、图片查看和处理软件、...
  • 解除360的系统压缩

    千次阅读 热门讨论 2019-10-02 15:41:07
    解除360的系统压缩问题工具解决 问题 不少小伙伴有在使用360的系统盘瘦身工具,在使用使用的过程中,为了增加系统盘的空间,我们可能选择了压缩系统盘。 系统盘压缩 系统盘压缩,顾名思义就是把系统盘的一些文件...
  • 版权说明:未经许可,不得转载 nsis简介: NSIS是一个开源的Windows系统下安装程序制作程序。它提供了安装、卸载、系统设置...对于制作好的安装包,有些时候可能需要在安装完成界面上添加一个可勾选的开机自启动的...
  • 软件exe打包压缩常用静默安装参数

    千次阅读 2019-01-14 15:34:16
    软件的安装采取全自动或半自动的方式进行。  一、Microsoft Windows Installer  如果某个软件是用 Windows Installer 打包的,那你就应该能在文件夹中看到 *.msi 文件。这是最典型的特征,这些文件通常可以使用...
  • LILO启动之后,如果你选择了Linux作为准备引导的操作系统,第一个被加载的东西就是内核。请记住此时的计算机内存中还不存在任何操作系统,PC(因为它们天然的设计缺陷)也还没有办法存取机器上全部的内存。因此
  • 手机怎么把视频压缩到最小

    千次阅读 2021-10-21 20:20:59
    手机怎么把视频压缩到最小,在手机上安装“王者剪辑app”,启动应用并进入一键剪辑中的“视频压缩”功能中, 批量导入或导入一个需要压缩的视频, 接着选择压缩类型,然后点击界面右上角的对勾按钮, 接下来就...
  • 单击“开始→程序”,你会发现一个“启动”菜单,这就是最经典的Windows启动位置,右击“启动”菜单选择“打开”即可将其打开,如所示,其中的程序和快 捷方式都会在系统启动时自动运行。最常见的启动位置如下: ...
  •  ...------------------将exe文件设置为自启动---------------- ...SC create myService binpath= c:\windows\system32\myService .exe ...------------------将tomcat设置为自启动----------
  • tomcat设置自启动后,启动或关闭tomcat最后使用 systemctl命令而不再是使用tomcat/bin目录中的startup.sh和shutdown.sh 五、systemctl常用命令 查看tomcat的状态 systemctl status tomcat.service 配置...
  • python压缩图片和视频

    千次阅读 2019-05-09 13:22:09
    往往要进行图片的传输和视频的传输,但因为用户上传的图片和视频所占用的大小问题而导致占用服务器的空间多,并且用户访问这些图片的时候因为图片或视频太大而长时间加载,所以要对用户上传的视频和图片进行压缩,...
  • 无损压缩算法专题——RLE算法实现

    千次阅读 2020-01-04 23:16:29
    本文是基于我的另一篇博客《无损压缩算法专题——无损压缩算法介绍》的基础上来实现的,RLE算法最简单的理解就是用(重复数,数据值)这样一个标记来代替待压缩数据中的连续重复的数据,以此来达到数据压缩的目的。...
  • 加载zip压缩的javascript代码以及在Egret H5实际应用

    千次阅读 热门讨论 2017-07-31 13:30:42
    下面是来自实际项目使用的技术分享,从最开始的简单压缩应用到最后的Egret H5项目实战。主要起因是策划对最快进入登录界面有硬性要求(3秒),那么最开始加载的文件越少越小越好。对H5的游戏程序进行压缩,可以大大缩小...
  • 作者前文介绍了Windows PE病毒, 包括PE病毒原理、分类及... 这些基础性知识不仅和系统安全相关,同样与我们身边常用的软件、操作系统紧密联系,希望这些知识对您有所帮助,更希望大家提高安全意识,安全保障任重道远。
  • 这几个软件正常卸载后都存在残留,有一个没卸载干净,就会拖家带口卷土重来。 遇到这种情况,小白除了杀下毒可能没什么好的办法,或者想到用魔法打败魔法。 以360安全卫士为例,杀毒、卸载...杀毒,两个无需启动。 ...
  • Manjaro 常用软件安装

    万次阅读 多人点赞 2019-01-27 00:19:40
    Manjaro 常用软件安装修改Home下的目录为英文archlinuxcn-keyringchromeFirefox -- 自带搜狗拼音JDK坚果云shadownsocks-qt5Filezilla- 免费的 FTP 解决方案Tmux - 分屏软件网易云音乐vim微信-deepinQQ截图工具...
  • 之前的介绍大都局限在表层,并未深入对比分析彼此的不同,因此在具体使用过程中很容易踩坑——例如此次对于dcm文件的压缩。 近期由于项目需要,外出给客户部署云平台,鉴于当地网络环境以及数据量的问题,急需对数据...
  • 在打开的对话框“常规”选项卡中,单击“压缩方式”下拉框选择合适的压缩方式,并将压缩选项下的“创建解压格式压缩文件”选项勾选,这时候会发现“压缩文件名”框中的文件扩展名变成“.exe”。 切换到“高级”...
  • 系统与压缩内存进程占用资源真解

    万次阅读 2018-10-31 20:26:49
    系统与压缩内存占用解决真解 相信来到我这篇帖子里的各位一定深受这玩意的折磨吧,百度上的方式都试过了,都不行,我向大家介绍一个能实际有效的解决这个问题的方法,就算以后出现类似的问题也能解决而且保证...
  • 适合 Ubuntu的8款最佳录屏软件

    千次阅读 2021-01-06 16:21:33
    Ubuntu 有一个自带录屏软件, 但是有缺陷。当你点击键盘上的Ctrl\Alt\Shift\R,它会自动触发全屏录制,使用相同的快捷方式结束录制。但是,最大的问题是,您无法设置自定义屏幕录制区域。此外,更改分辨率、比特率和...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 154,956
精华内容 61,982
关键字:

压缩软件如何自启动