package five;
import java.io.*;
import java.text.DecimalFormat;
import java.util.*;
/**
可以为这个类添加额外的方法及数据成员.
ID就是指学号, 下面的作者一定要写上你的名字和学号
作业中出现的示范数据abdc001需要改成学生的学号数据
@author YOUR NAME and ID
@version THE DATE
**/
public class TextZip {
public static String code;
public static boolean flag;
public static int count_huffman,count_fileName,count_fileLength,count_Time;
public static String huffman_code,fileName_code,time;
public static void decompress(BitReader br, TreeNode huffman, FileOutputStream fw) throws Exception {
// IMPLEMENT THIS METHOD
TreeNode temp_node=huffman;
int headLength=count_huffman+count_fileName+count_Time+1;
for(int i=0;i<headLength;i++)
{
br.next();
}
while(br.hasNext())
{
if(br.next())
{
if(temp_node.isLeaf())
{
CharFreq cf=(CharFreq) temp_node.getItem();
fw.write(cf.getChar()); //是叶子结点的话,直接写入文件中
temp_node=huffman;
}
else {
temp_node=temp_node.getRight(); //不是叶子结点,则向右子树继续
}
}
else {
if(temp_node.isLeaf())
{
CharFreq cf=(CharFreq) temp_node.getItem();
fw.write(cf.getChar()); //是叶子结点的话,直接写入文件中
temp_node=huffman;
}
else {
temp_node=temp_node.getLeft(); //不是叶子结点,则向左子树继续
}
}
}
}
public static TreeNode removeMin(ArrayList a) {
int minIndex = 0;
for (int i = 0; i < a.size(); i++) {
TreeNode ti = (TreeNode)a.get(i);
TreeNode tmin = (TreeNode)a.get(minIndex);
if (((Comparable)(ti.getItem())).compareTo(tmin.getItem()) < 0)
minIndex = i;
}
TreeNode n = (TreeNode)a.remove(minIndex);
return n;
}
public static TreeNode buildTree(ArrayList trees) throws IOException {
// IMPLEMENT THIS METHOD
ArrayList<TreeNode> trees_copy=trees;
TreeNode leftNode=null,rightNode=null,fatherNode;
while(!trees_copy.isEmpty())
{
leftNode=removeMin(trees_copy);
leftNode.flag=false;
if(!trees_copy.isEmpty())
{
rightNode=removeMin(trees_copy);
rightNode.flag=false;
CharFreq cl=(CharFreq)leftNode.getItem();
CharFreq cr=(CharFreq)rightNode.getItem();
fatherNode=new TreeNode(new CharFreq('\u0000',cl.getFreq()+cr.getFreq()));
fatherNode.setLeft(leftNode);
fatherNode.setRight(rightNode);
fatherNode.flag=false;
trees_copy.add(fatherNode);
}
else {
break;
}
}
return leftNode;
}
public static void TLV(File file,TreeNode huffman,FileWriter fw) throws IOException
{
bianliTree(huffman, "");
huffman_code=code; //哈弗曼编码
fileName_code=file.getName(); //文件名称
count_fileLength=(int) file.length(); //文件长度
time=new Date().toString(); //访问时间
}
public static void compress(FileInputStream fr, TreeNode huffman, BitWriter bw) throws Exception {
// IMPLEMENT THIS METHOD
int i=0;
byte[] byte_huffman=huffman_code.getBytes();
for(i=0;i<byte_huffman.length;i++)
{
count_huffman++;
writeFile(huffman, byte_huffman[i], bw);
}
byte[] byte_fileName=fileName_code.getBytes();
for(i=0;i<byte_fileName.length;i++)
{
count_fileName++;
writeFile(huffman, byte_fileName[i], bw);
}
String fileLength=Integer.toBinaryString(count_fileLength);
byte[] byte_length=fileLength.getBytes();
for(i=0;i<byte_length.length;i++)
{
count_fileLength++;
writeFile(huffman, byte_length[i], bw);
}
byte[] byte_time=time.getBytes();
for(i=0;i<byte_time.length;i++)
{
count_Time++;
writeFile(huffman, byte_time[i], bw);
}
byte[] read_byte=new byte[1024];
while(fr.available()>0)
{
fr.read(read_byte);
for(int j=0;j<1024;j++)
{
if(read_byte[j]<0)
i=256+read_byte[j];
else {
i=read_byte[j];
}
writeFile(huffman, i, bw);
}
}
}
public static void writeFile(TreeNode huffman,int i,BitWriter bw) throws Exception
{
char c=(char)i;
flag=false;
code="";
TreeNode treeNode=huffman;
preVisitTree(treeNode, "", c);
System.out.println(code);
for(int k=0;k<code.length();k++)
{
if(code.charAt(k)=='0')
{
bw.writeBit(0);
}
else {
bw.writeBit(1);
}
}
}
public static void bianliTree(TreeNode root , String hfmCode){
//如果根不为0
if(root != null){
String lCode = hfmCode + "0";
bianliTree(root.getLeft() , lCode);
String rCode = hfmCode+"1";
bianliTree(root.getRight() , rCode);
if(root.isLeaf())
{
CharFreq cf=(CharFreq) root.getItem();
getHuffmanCode(hfmCode,cf.getChar());
}
else {
getHuffmanCode(hfmCode,'\u0000');
}
}
}
public static void preVisitTree(TreeNode root , String hfmCode,char c){
//如果根不为0
if(flag==false)
{
CharFreq cf=null;
if(root != null){
if(root.isLeaf())
{
cf=(CharFreq) root.getItem();
if(cf.getChar()==c)
flag=true;
}
setHuffmanCode(hfmCode);
String lCode = hfmCode + "0";
preVisitTree(root.getLeft() , lCode,c);
String rCode = hfmCode+"1";
preVisitTree(root.getRight() , rCode,c);
}
}
}
public static void getHuffmanCode(String str,char c)
{
code+=(String.valueOf(c)+str);
}
public static void setHuffmanCode(String str)
{
code=str;
}
public static TreeNode setFalse(TreeNode treeNode)
{
ArrayDeque<TreeNode> queue=new ArrayDeque<TreeNode>();
TreeNode treeNode2=treeNode;
queue.push(treeNode2);
while(!queue.isEmpty())
{
treeNode2=queue.pop();
treeNode2.flag=false;
if(treeNode2.getLeft()!=null)
{
queue.push(treeNode2.getLeft());
}
if(treeNode2.getRight()!=null)
{
queue.push(treeNode2.getRight());
}
}
return treeNode;
}
public static ArrayList<TreeNode> readFrequencies(File file) throws Exception {
// IMPLEMENT THIS METHOD
FileInputStream fis=new FileInputStream(file);
int i;
int[] byte_count=new int[256];
byte[] byte_array=new byte[64];
String str=null;
while(fis.available()>0)
{
fis.read(byte_array);
for(int j=0;j<64;j++)
{
if(byte_array[j]<0)
{
int index=byte_array[j]+256; //正数存储在0-127,负数存储在128-255
byte_count[index]++;
}
else {
byte_count[byte_array[j]]++;
}
}
}
fis.close();
ArrayList<TreeNode> arrayList=new ArrayList<>();
char c;
for(i=0;i<256;i++)
{
c=(char)i;
arrayList.add(new TreeNode(new CharFreq(c, byte_count[i])));
}
return arrayList;
}
public static void main(String[] args) throws Exception {
TextZip tz=new TextZip();
File file=new File("qqbn_gygg.flv");
File file2=new File("qqbn_gygg.hz");
File file3=new File("qqbn.flv");
FileWriter fw=new FileWriter(file2);
ArrayList<TreeNode> arrayList=readFrequencies(file); //读每个字符出现的频率
TreeNode head=buildTree(arrayList); //根据频率构建哈弗曼树
FileInputStream fis=new FileInputStream(file);
BitWriter bw=new BitWriter(file2);
TLV(file2,head,fw);
compress(fis, head, bw); //把file1压缩到file2里面
BitReader br=new BitReader(file2);
FileOutputStream fos=new FileOutputStream(file3);
decompress(br, head, fos); //把file2解压到file3里面
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
对于任意一个文件进行压缩,压缩后的文件名为原文件名称去掉后缀加上.hz,例如,原来的未压缩文件的名字为a.txt,压缩后为a.h...
共19个文件
class:8个
java:5个
flv:2个
需积分: 50 24 下载量 64 浏览量
2014-07-02
13:08:35
上传
评论 3
收藏 3.65MB ZIP 举报
温馨提示
压缩过程可能需要几分钟 2. 使用霍夫曼编码原理(参照以前的作业), 对于任意一个文件进行压缩,压缩后的文件名为原文件名称去掉后缀加上.hz,例如,原来的未压缩文件的名字为a.txt,压缩后为a.hz,压缩后的文件信息使用TLV结构(TYPE-LENGTH-VALUE),文件信息包括霍夫曼编码码表,文件名称,文件长度,文件访问时间等,当然还包括压缩的内容。 要求:(a) 提供压缩与解压缩功能,提供查看压缩文件信息功能。 (b) 需要使用的类有File, 以及霍夫曼压缩作业提供的程序。 (c) 压缩内容不再是文本字符数据,而是任意二进制文件,请压缩附件中的“全球变暖的公益广告视频”(qqbn_gygg.flv)。 注意:(a) 先假设压缩的文件的长度都不大,不考虑效率问题,可以使用缓存。 (b) 以前的霍夫曼压缩文件的程序可以参考,可以修改。
资源推荐
资源详情
资源评论
收起资源包目录
five_java.zip (19个子文件)
five_java
.project 385B
qqbn.flv 1.84MB
qqbn_gygg.flv 1.84MB
src
five
TextZip.java 7KB
BitWriter.java 5KB
CharFreq.java 482B
TreeNode.java 2KB
BitReader.java 3KB
.settings
org.eclipse.jdt.core.prefs 598B
qqbn_gygg.hz 57KB
.classpath 301B
bin
five
BitWriter$InvalidBitException.class 451B
BitReader.class 2KB
TreeNode.class 2KB
BitWriter.class 3KB
TextZip.class 7KB
CharFreq.class 1KB
BitWriter$BitWriterClosedAlreadyException.class 487B
BitReader$NoBitsLeftToReturn.class 448B
共 19 条
- 1
资源评论
猿哥
- 粉丝: 6
- 资源: 35
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功