Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 807|回复: 0

使用huffman编码压缩文件并读取 java实例

[复制链接]

该用户从未签到

发表于 2011-9-19 13:54:26 | 显示全部楼层 |阅读模式
已经实现了huffman的编码过程,但是不知道如何用编码方式对文件进行压缩.下面给出简单的代码。
对范例文件test.dat的压缩比例为:126byte/27byte


    import java.io.BufferedInputStream;  
    import java.io.BufferedOutputStream;  
    import java.io.File;  
    import java.io.FileInputStream;  
    import java.io.FileOutputStream;  
    import java.io.IOException;  
    import java.util.Scanner;  
      
    public class WriteBinary  
   {  
       //由huffman算法产生的编码表  
       String[] code = {"0", "10", "11"};  
         
       /**
        * 测试函数
        *@param args
        */  
       public static void main(String args[])  
       {  
           WriteBinary w = new WriteBinary();  
           try  
          {  
               w.write("test.dat", "test.hfm"); //将test.dat文件的内容进行编码写入test.hfm  
               System.out.println(w.read("test.hfm")); // 从压缩后的文件中还原出源文件的内容,并打印  
           } catch (IOException e)  
           {  
               e.printStackTrace();  
           }  
       }  
         
       /**
        * 对源文件进行编码,并写入目标文件
        *@param from 需要进行编码的源文件
        *@param to 目标文件
        *@throws IOException
        */  
       public void write(String from, String to) throws IOException  
       {  
           File fromFile = new File(from);  
           Scanner scan = new Scanner(fromFile);  
           File f = new File(to);  
          BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(f));  
           while(scan.hasNextLine())  
           {  
               String line = scan.nextLine();  
               System.out.println(line);  
                 
               //将文件中的所有字符用编码替换  
               //如果字符种类很多,应该将编码对应表存入数组转换,而不应该像下面一样硬编码  
               line = line.replace("a", code[0]);  
              line = line.replace("b", code[1]);  
               line = line.replace("c", code[2]);  
              System.out.println(line);  
               byte[] buf = new byte[line.length() / 7];  
                 
               //将编号码的String进行转化,转化成 byte数组,并存入文件,除去符号位,每7位对应1byte  
               for(int i = 0; i * 7 + 7 <= line.length(); i ++)  
                   buf = Byte.valueOf(line.substring(i * 7, i * 7 + 7), 2);  
               out.write(buf);  
           }  
           out.flush();  
           out.close();  
           scan.close();  
       }  
         
       /**
        * 从编码后的文件中读取并解码,返回原文件的内容
        *@param file 编码后的文件
        *@return 源文件内容的字符串
        *@throws IOException
        */  
       public String read(String file) throws IOException  
       {  
           BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));  
           StringBuffer resultStr = new StringBuffer();    //最终需要返回的结果  
           StringBuffer codeStr = new StringBuffer();  //需要解析的编码的字符串  
           byte[] buf = new byte[1];  
            
           //从文件中读出byte数组,并转化成二进制字符串  
           while(in.read(buf) != -1)  
          {  
                  //把从文件中读取出的byte转化成二进制字符串  
                   String bStr = Integer.toBinaryString(buf[0]);  
                  StringBuffer temp = new StringBuffer();  
                   //对二进制字符串补0,因为 Integer.toBinaryString方法转化成的二进制数会省略前面的若干个0  
                  for(int j = 0; j < 7 - bStr.length(); j ++)  
                       temp.append('0');  
                   //将读取出并转化好的二进制字符串放入codeStr,留待下一步对其进行解码  
                   codeStr.append(temp + bStr);  
           }  
            
           in.close();  
     
           //对上面转化成的二进制字符串进行解码  
               for(int i = 0; i < codeStr.length(); i ++)  
               {  
                   //huffman解码过程  
                   if(codeStr.charAt(i) == '0')  
                       resultStr.append('a');  
                  else  
                  {  
                      i++;  
                      if(i >= codeStr.length())  
                         break;  
                      if(codeStr.charAt(i) == '0')  
                          resultStr.append('b');  
                      else  
                          resultStr.append('c');  
                  }  
              }  
          return new String(resultStr);  
      }  
}  

test.dat的内容

aaabbcaaabbcbaaaabbcaaabbcbaaaabbcaaabbcbaaaabbcaaabbcbaaaabbcaaabbcbaaaabbcaaabbcbaa
aabbcaaabbcbaaaabbcaaabbcbaaaabbcaaabbcba

ps:

给出的代码只能对转换成二进制后,二进制位为7的倍数的文件进行压缩,如果需要弥补这个问题,需要在编码后的文件头中写入源文件的大小,本程序为简便起见,未作处理
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2024-6-26 16:42 , Processed in 0.389796 second(s), 47 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表