和第四题一样同样是各种东拼西凑的结果,希望对一部分人有帮助。要用的话请至少改一下变量名和函数顺序并且搞懂为什么,不要直接抄袭。在此感谢陈德创大佬的无私帮助以及陈万庆老师提供的音频测试文件
看之前请先搞懂RLE算法的原理和部分代码实现
RLE算法原理及C语言实现

原题:

涉及知识点:文件读写、位操作、内存管理、结构体定义、RLW算法、命令行参数

要求:

编写一个程序,可以在命令行输入参数,完成指定文件的压缩解压

命令行参数如下

rle file1 –c(-d) file2

第一个参数为可执行程序名称,第二个参数为原始文件名,第三个参数为压缩或解压缩选项,第四个参数为新文件名

问题分析

题目已经提示了要求用RLE算法结合位运算来实现解压缩,经过思考可以知道所有文件的本质都是二进制文件,这道题需要通过位操作和RLE算法直接压缩二进制代码。现在的问题有:

1.什么是RLE算法?如何用C语言实现RLE算法?

2.如何按照二进制的方式分块读入文件并在文件压缩和解压缩后输出?

解决方案(思路)

RLE算法的本质在于区分连续字节块和非连续字节块,用单独的字节来存储连续字节块和非连续字节块关的长度。对于其原理和代码实现,我在阅读了文档后自己进行了整理并写了一篇博客,链接如下。由于报告的篇幅原因就没有把全文内容附在报告内,后面的内容会直接引用博客中的概念和代码。

https://blog.csdn.net/zimuzi2019/article/details/106583064

对于单个文件,传入文件后通过文件指针每次读入一定数量的字节数据,这些字节数据传入函数进行压缩编码或者解压解码后再把新数据写入指定的新文件

算法分析

根据输入的命令行参数进行对应操作

  • 若为压缩操作则将指定要压缩的文件名和要输出的文件名传入Compression函数,分别创建两个文件指针指向输入和输出文件,两个申请的内存空间中inbuf用于存储待压缩的数据块,outbuf用于存储待输出的数据块。然后用fread函数每次读入定长的字节数,并用length记录成功读入的字节数。把读取的字节数length,指向两块申请的内存空间inbuf和outbuf,存储待输出数据块的数组outbuf的大小传入RLe_Encode函数进行压缩编码。在RLe_Encode函数内建立输入指针src指向inbuf。循环遍历inbuf数组直到inbuf剩余字节为0。循环时用IsrepetitionStart函数判断,若连续的三个字节数据相同时则利用GetRepetitionCount函数得到重复的个数并将连续字节块和记录连续字节块的字节写入输出数组outbuf同时移动数组指针。否则利用GetNonRepetitionCount函数得到不重复的个数并逐个写入outbuf数组。

  • 若为解压缩操作则将指定要解压的文件名和要输出的文件名传入Decompression函数,分别创建两个文件指针指向输入和输出文件。两个申请的内存空间中inbuf用于存储待解压缩的字节块,outbuf用于存储待输出的字节块。然后用fread函数每次读入定长的字节数,并用length记录成功读入的字节数。把读取的字节数length,指向两块申请的内存空间inbuf和outbuf,存储待输出数据块的数组outbuf的大小传入RLe_Decode函数进行解压缩解码。在RLe_Decode函数内建立输入指针src指向inbuf,循环遍历inbuf数组,若发现连续重复标记则则将标识字节后面的数据重复复制n份写入outbuf。否则说明是非连续数据,将标识字节后面的n个数据复制到outbuf。n值由存储长度信息的字节块的值确定。

源代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>int IsrepetitionStart(unsigned char *src,int srcLeft){if(srcLeft<3){return 0;}if((src[0]==src[1])&&(src[1]==src[2])){return 1;}return 0;
}int  GetRepetitionCount(unsigned char *src,int srcLeft){int repeatedbuf=src[0];int length=1;while(length<srcLeft&&length<0x7f&&src[length]==repeatedbuf){length++;}return length;
}int GetNonRepetitionCount(unsigned char *src,int srcLeft){if(srcLeft<3){return srcLeft;}int length=2;int a=src[0],b=src[1];while(length<srcLeft&&length<0x7f&&((a!=b)||(b!=src[length]))){a=b;b=src[length];length++;}return length;
}int Rle_Encode(unsigned char *inbuf,int inSize,unsigned char *outbuf,int onuBufSize)
{unsigned char *src=inbuf; int i;int encSize=0;int srcLeft=inSize;       while(srcLeft>0){         int count=0;if(IsrepetitionStart(src,srcLeft)){ if((encSize+2)>onuBufSize){      return -1;} count=GetRepetitionCount(src,srcLeft); outbuf[encSize++]=count|0x80;          outbuf[encSize++]=*src;             src+=count;                            srcLeft-=count;}else{count=GetNonRepetitionCount(src,srcLeft); if((encSize+count+1)>onuBufSize){ return -1;}outbuf[encSize++]=count;for(i=0;i<count;i++){           outbuf[encSize++]=*src++;}srcLeft-=count;}}return encSize;
}int Rle_Decode(unsigned char *inbuf,int inSize,unsigned char *outbuf,int onuBufSize){unsigned char *src=inbuf;int i;int decSize=0;int count=0;while(src<(inbuf+inSize)){unsigned char sign=*src++;int count=sign & 0x7F;if((decSize+count)>onuBufSize){ return -1;}if((sign&0x80)==0x80){          for(i=0;i<count;i++){outbuf[decSize++]=*src;}src++;}else{for(i=0;i<count;i++){outbuf[decSize++]=*src++;}}           }return decSize;
}int Compression(char*Inputfilename,char*Outputfilename){FILE *Input=fopen(Inputfilename, "rb");FILE *Output=fopen(Outputfilename, "wb");if (Input==NULL||Output==NULL){printf("We can't open the file successfully!");}unsigned char*inbuf;unsigned char*outbuf;inbuf =(unsigned char*)malloc((sizeof(unsigned char))*1024*1024*1024);outbuf=(unsigned char*)malloc((sizeof(unsigned char))*1024*1024*1024);int length;while ((length=fread(inbuf, sizeof(unsigned char),1024,Input))!= 0){int tmp=Rle_Encode(inbuf,length,outbuf,1024*1024*1024);if(tmp==-1){return -2;}fwrite(outbuf, sizeof(unsigned char),tmp,Output);}fclose(Input);fclose(Output);
}int Decompression(char*Inputfilename,char*Outputfilename){FILE *Input=fopen(Inputfilename, "rb");FILE *Output=fopen(Outputfilename, "wb");if (Input==NULL||Output==NULL){printf("We can't open the file successfully!");}unsigned char*inbuf;unsigned char*outbuf;inbuf =(unsigned char*)malloc((sizeof(unsigned char))*1024*1024*1024);outbuf=(unsigned char*)malloc((sizeof(unsigned char))*1024*1024*1024);int length;while((length=fread(inbuf, sizeof(unsigned char),1024*1024*1024,Input))!=0){int tmp=Rle_Decode(inbuf,length,outbuf,1024*1024*1024);if(tmp==-1){return -2;}fwrite(outbuf, sizeof(unsigned char),tmp,Output);}fclose(Input);fclose(Output);
}int main(int argc,char**argv)
{if(strcmp(argv[2],"-c")==0){Compression(argv[1],argv[3]);}else if(strcmp(argv[2],"-d")==0){Decompression(argv[1],argv[3]);}  return 0;
}

测试数据(输入,输出):

压缩txt文本文件




压缩bmp图形文件





压缩mp3音频文件(感想陈万庆老师提供的英语听力测试文件!)




尝试播放后会发现解压的音频可以正常播放(我听过一遍,确实一样,嗯),和原内容一样

RLE压缩解压算法的完整实现相关推荐

  1. 文件压缩c语言程序代码,C语言程序设计之RLE压缩解压算法

    先介绍一下RLE压缩算法: 游程编码(Run-Length Encoding, RLE)又称行程长度编码或者变动长度编码法,在控制理论中对于二值图像而言是一种编码方法,对连续的黑,白向像素以不同的码字 ...

  2. 【分享】AspxZip v2.0 在线压缩解压ZIP文档

    下载地址: http://download.csdn.net/detail/rrrfff/5756977 当前版本:2.0.20140609 AspxZip v2.0 特点: 1.能够在支持 ASP. ...

  3. c# rar解压大小_Linux压缩解压指令-bzip2、xz、compress、rar

    前面已经进介绍过Linux中用到的归档程序tar,文件压缩解压程序gzip.zip,今天继续介绍另外四种常见的压缩程序bzip2.compress.xz.rar. 文件压缩 bzip2 bzip2采用 ...

  4. mac 命令行 解压7z文件_命令行压缩解压7z

    命令行压缩解压一 7z 1) 简介7z,全称7-Zip, 是一款开源软件.是目前公认的压缩比例最大的压缩解压软件.主页:http://www.7-zip.org/中文主页:http://7z.spar ...

  5. linux+shell+解压命令,linux shell 压缩解压命令

    .tar 解包:tar xvf FileName.tar 打包:tar cvf FileName.tar DirName (注:tar是打包,不是压缩!) --------------- .gz 解压 ...

  6. 7z 命令行压缩解压详解-中文版

    1) 简介 7z,全称7-Zip, 是一款开源软件.是目前公认的压缩比例最大的压缩解压软件. 主页:http://www.7-zip.org/ 中文主页:http://7z.sparanoid.com ...

  7. java 7zip解压_Apache Commons Compress介绍-JAVA压缩解压7z文件

    7zip(下面简称7z)是由Igor Pavlov所开发的一种压缩格式,主要使用的压缩算法是LZMA/LZMA2.7z是一种压缩比非常高的格式,这与其压缩算法LZMA有直接关系,所以很多大文件都是用7 ...

  8. SAPCAR 压缩解压软件的使用方法

    SAPCAR 是 SAP 公司使用的压缩解压软件,从 SAP 网站下载的补丁包和小型软件基本都是扩展名为 car 或 sar 的,它们都可以用 SAPCAR 来解压.下面是它的使用说明: 用法: 创建 ...

  9. WebAPI性能优化之压缩解压

    有时候为了提升WebAPI的性能,减少响应时间,我们会使用压缩和解压,而现在大多数客户端浏览器都提供了内置的解压支持.在WebAPI请求的资源越大时,使用压缩对性能提升的效果越明显,而当请求的资源很小 ...

最新文章

  1. 面向固态激光雷达和惯导的里程计和建图
  2. 巴菲特+查理芒格+投资理论+经典语录+给韭菜的启示
  3. HDU2612 Find a Way BFS
  4. 前端设置使用rem最经典代码
  5. pandas添加、修改dataframe中index的列名
  6. python几种排序_Python实现几种排序算法
  7. 【SpringMVC 笔记】控制器 Controller 与 RestFul 风格
  8. 1018Big Number用斯特林公式的简化公式和不用公式解决
  9. linux删除指定大小的文件,Linux 脚本删除大于指定大小的文件
  10. 数据结构 第一章 绪论
  11. 不依赖第三方环境和服务
  12. 宝塔控制面板如何添加伪静态
  13. 傅里叶变换的性质及证明(CTFT)
  14. 【外挂对抗总结】小游戏H5小程序网页游戏分析
  15. qq红包代码加群链接
  16. python, numpy中的.tile方法解释
  17. influx配置文件详解
  18. vue2.9.6版本下创建vue-cli脚手架
  19. GUI,UGUI,NGUI三种编辑UI界面的插件
  20. 亚马逊AWS进入中国

热门文章

  1. 偶然一次机会对xposed插件学习记录(微信自动抢红包原理研究,适配微信8.0)
  2. window.onresize和window.addEventListener
  3. Window bat批处理命令
  4. Latent SVM
  5. 手机淘首页怎么设置微博一键直达?制作直达链接最全图文设置教程
  6. Key Dependent Message(KDM)
  7. android手机后台流量,安卓手机如何控制流量
  8. 企业级负载均衡解决方案之八:腾讯云负载均衡解决方案CLB
  9. (WPS)Excel表格中批量删除指定字符
  10. 吴镝:TiDB 在今日头条的实践