`
文昌平蓝杰
  • 浏览: 56171 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

压缩的过程

阅读更多

压缩:

   1.压缩思路:

1.把文件的字符读出来,记录出现过的字符及其出现的次数。构造相应的结点。

2.把结点组建成一棵哈夫曼树,并获得哈夫曼编码。

3.利用哈夫曼编码,写入头文件和文件内容。

   2.读字符,存队列

1.读取文件信息,存放于数组之中,下标作为ask码值

public int[] countChar(String path){
			File file = new File(path);//根据文件地址创建文件对象
			int[] c = new int[256];

			for(int i=0;i<c.length;i++){
				c[i]=0;
			}
			try {
				//创建输出流对象
				InputStream is = new FileInputStream(file);
				//一个一个的读出
				while(is.available()>0){
					int i = is.read();   //将文件读入到 数组 中
					c[i]++;
				}
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} 
			return c;
		}
 

2.构建结点,建造树。

Queue q =  new Queue();//实例化队列对象
		HFMTree tree = new HFMTree();//实力化一个树对象
		//用于记录文件中出现过的字符的次数,下标指 ask码值对应的字符 
		int[] ch = this.countChar(path);
		//利用次数数组创建结点对象,加入队列
		for(int i=0;i<ch.length;i++){
			if(ch[i]!=0){
				//如果出现过该字符,则创建结点,加入队列
				Node node = new Node(((char)i)+"", ch[i]);
				q.add(node);
			}
		}
		tree.creatTree(q);  //利用结点构建树
		q = tree.ergodic(tree.getRoot(),""); //遍历树,给结点绘制对应的编码,存储于队列之中
 

   3.第三步骤:

1.头文件

1.头文件包括出现字符的编码。

@  队列长度(int) 

@  文件末尾补零情况   

@  每一个队列元素    

@字符

@编码长度

@最后一次补零的个数

@编码的具体信息

这是头文件的内容格式,也就是必要的一些内容,因为文件本身是一个独立的个体,要考虑到之后能够读取出来,所以必须要存入如上戏信息,不然在打开时,因为不知道文件信息,而无法打开。

2.写入头文件

public void compressFile(String path,String newpath){
		File file = new File(path);  //将地址解析成具体的文件
		File newfile = new File(newpath);  //将地址解析成具体的文件
		
		try {
			//创建输出流对象
			InputStream bis = new FileInputStream(file);
			BufferedInputStream is = new BufferedInputStream(bis);
			//创建输入流对象 
			OutputStream bos = new FileOutputStream(newfile);
			BufferedOutputStream os = new BufferedOutputStream(bos);
			/***将队列读入文件***/
			os.write(q.size());                                              
			//文件最后补零的情况
			int addzero = 0,cache = 0;
			for(int i=0;i<q.size();i++){
				//文件长度 = 字符次数   * 编码长度
				cache += q.get(i).getCount()*q.get(i).getSymbol().length(); 
			}
			addzero = 8-cache%8; //文件补零的情况
			/***写入文件末尾补零情况****/
			os.write(addzero);
			/****写入编码信息*****/
			for(int i=0;i<q.size();i++){
				//获取信息
				int xchar = q.get(i).getData().charAt(0); 
				int xsize = q.get(i).getSymbol().length()/8+1;
				int xzero = 8-q.get(i).getSymbol().length()%8;
				//写入信息
				os.write(xchar);//字符
				os.write(xsize);//长度
				os.write(xzero);//补零个数
				//写入编码
				String string = q.get(i).getSymbol();
				String waitString = ""; //用来缓存的字符串
				//写入编码的前几位
				for(int j=0;j<xsize-1;j++){
					waitString = "";
					waitString = string.substring(0, 8);
					string = string.substring(8);
					int xString = changeString(waitString);
					os.write(xString);
				}
				//写入编码最后一位
				for(int j=0;j<xzero;j++){
					string += "0";
				}
				int xString = changeString(string);
				os.write(xString);//写入编码内容
			}
 

3.写入文件内容

String writeString = ""; 
			while(is.available()>0){
				int i = is.read();   //将文件读出来
				for(int j=0;j<q.size();j++){//用循环找到对应的字符编码
					boolean bool = false; //需要寻找的字符还未找到
					//如果找到了
					if(q.get(j).getData().equals((((char)i)+""))){
						int x=0;
						while(true){
							writeString += q.get(j).getSymbol().charAt(x)+"";
							x++;
							//如果是因为溢出
							if(writeString.length()==8){
								int xString = changeString(writeString);
								os.write(xString);             //写入一个字节
								writeString = "";
							}
							//如果是因为数字位数不足
							if(x==q.get(j).getSymbol().length()){
								bool = true;
								break;
							}
						}
					}//如果找到文件
					if(bool==true){
						break;
					}
				}
			}
			//对最后一个经行处理
			if(writeString.length()>0){
				int x = 8-writeString.length();
				for(int i=0;i<x;i++){
					writeString += "0";
				}
				int xString = changeString(writeString);
				os.write(xString);
			}
			os.close();//关闭输出流
			is.close();//关闭输入流
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} 
	}	
 

这样就对一个文本文件实现了压缩功能。剩下的解压,无非是根据文件信息,一步一步经行反步骤,解压开来。这种压缩方式在我的测试中发现有一个缺点,当文件末尾是字符时,就正常运行,当文件最后一个是汉字时,最后一个汉字会被改变,所以这一点暂时还没考虑到,留着广大读者去思考吧。呵呵!

分享到:
评论

相关推荐

    数字图像压缩编码算法及压缩过程的实现

    "数字图像压缩编码算法及压缩过程的实现" 本文主要讲解了数字图像压缩编码算法及压缩过程的实现,特别是 JPEG 编码算法的原理和实现过程。首先,文章介绍了图像压缩的目的和方法,图像压缩的目的是为了减少图像的...

    图象压缩(JPEG)编码算法及压缩过程的实现

    【有损压缩】意味着在压缩过程中,部分信息会被永久丢弃,这与无损压缩(如PNG、GIF)形成对比。JPEG适合于对图像质量要求不是非常高的场景,比如网页上的图片或者存储大量的个人照片。 总之,JPEG编码算法通过DCT...

    compress.rar_内燃机_压缩机_压缩过程编程_曲轴

    "compress.rar_内燃机_压缩机_压缩过程编程_曲轴"这个压缩包文件,显然与内燃机的压缩过程模拟和曲轴运动分析有关,特别是通过编程实现这一过程的计算和可视化。 首先,我们来深入理解内燃机的压缩过程。内燃机的...

    航空活塞发动机-压缩过程.pptx

    在这个发动机中,压缩过程是至关重要的一个环节,它直接影响到发动机的性能和效率。 一、压缩过程的进行 在航空活塞发动机中,压缩过程始于活塞位于下死点,即活塞处于最低位置,此时进气门已经关闭,气缸内充满...

    linux启动流程分析---内核解压缩过程

    Linux 启动流程分析 --- 内核解压缩过程 Linux 启动流程中的内核解压缩过程是一个非常重要的步骤,它决定了 Linux 内核的正确加载和执行。在这个过程中,内核压缩和解压缩代码都在目录 kernel/arch/arm/boot/...

    JPEG编码算法及压缩过程

    JPEG编码算法的核心是基于离散余弦变换(DCT)的图像数据压缩,下面将详细阐述其原理和压缩过程。 一、JPEG编码算法基础 1. 颜色空间转换:JPEG首先将图像从RGB(红绿蓝)颜色空间转换到YCbCr颜色空间。Y表示亮度...

    数据结构之霍夫曼压缩,更易理解文件压缩过程

    在本文中,我们将深入探讨霍夫曼编码的基本原理、实现步骤以及其在文件压缩过程中的应用。 首先,霍夫曼编码的核心思想是利用字符出现的频率差异进行编码。频繁出现的字符赋予较短的编码,而较少出现的字符则赋予较...

    图象压缩(JPEG)编码算法及压缩过程的实现

    - 有损压缩允许图像在压缩/解压缩过程中接受一定程度的失真,尤其适用于图像数据,因为它们往往源自对现实世界的不完美表示。例如,图像中的微小灰度变化可能在视觉上不可察觉。 - 初始尝试将语音信号压缩技术应用...

    matlab实现jpeg压缩过程_MATLAB程序

    在MATLAB环境中实现JPEG压缩过程,涉及到多个关键步骤,这些步骤将在以下内容中详细阐述。 首先,JPEG压缩的核心是离散余弦变换(DCT,Discrete Cosine Transform)。在MATLAB中,可以使用`dct2`函数来执行二维DCT...

    JPEG压缩过程、算法详解

    ### JPEG压缩过程、算法详解 #### 一、JPEG压缩简介 JPEG(Joint Photographic Experts Group)是一种广泛应用于静态图像压缩的标准格式,它以其高效的压缩比和高质量的图像输出而著称。JPEG支持有损压缩和无损...

    颜色空间转换+DCT变换+量化+霍夫曼编码+解压缩过程实现彩色图像压缩,matlab平台

    本项目在MATLAB平台上实现了一个完整的彩色图像压缩流程,包括颜色空间转换、离散余弦变换(DCT)、量化、霍夫曼编码以及解压缩过程。下面将详细介绍这些步骤及其相关知识点。 1. **颜色空间转换**: 颜色空间转换...

    JPEG2000图像压缩过程及原理概述图像算法

    ### JPEG2000图像压缩过程及原理概述 #### 一、引言 在多媒体技术蓬勃发展的今天,图像压缩技术成为解决数据存储和传输瓶颈的关键。传统的JPEG标准虽然广泛应用于图像压缩,但在压缩效率、图像质量和灵活性方面...

Global site tag (gtag.js) - Google Analytics