📄 compressfile.java
字号:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.swing.JOptionPane;
//数据压缩类,分别做压缩头文件,压缩源文件,以及处理与HuffmanCoding中一些数据的关系
public class CompressFile {
private HuffmanCoding hc=new HuffmanCoding();
//压缩头文件,把所有256个byte出线的频率用writeInt写入头文件,包括出线0次的
private void outputFrequencies(DataOutputStream fout) throws IOException{
for(int j=0; j<256; j++){
fout.writeInt(hc.dat[j]);
}
}
//压缩源文件,把若干个code合并成int,然后写入压缩文件
private void outputCode(String input,DataOutputStream fout)throws IOException{
int b=0;//不满一个int的code的合并数据
int a=32;//剩下的空位
int ch1;//以readbyte读入原文件
try{
DataInputStream fin=new DataInputStream(new BufferedInputStream(new FileInputStream(input)));
while(true){
ch1=fin.readByte()+128;//防止数组越界,使-128~127->0~255
if(a>hc.node[ch1].codewordLen){//判断下一个读入的code长度是否小于原来剩下的空位
b=b|(hc.node[ch1].code<<(a-hc.node[ch1].codewordLen));//如果是,那么把这个新code左移之后加入原来剩下的不满int的b中
a=(a-hc.node[ch1].codewordLen);}//重新确定剩下的空位a
else{
int mask=~(~0<<a);//如果超过那么做一个尾部剩下a位的mask
b|=mask & (hc.node[ch1].code>>(hc.node[ch1].codewordLen-a));//把新读入的code戒出原来缺少的一段,然后通过右移和mask补到原来剩下的code串中
fout.writeInt(b);//把补全了的int(也就是code串)输入到文件当中
b=(hc.node[ch1].code<<(31+a-hc.node[ch1].codewordLen))<<1;//把刚才新读入的 code剩下部分移位后作为新的不满int的code串
a=a-hc.node[ch1].codewordLen+32;//重新确定剩下的空位a
}
}
}catch(IOException n){;
fout.writeInt(b);//捕获EOFException异常,然后把剩下的最后不满的int的code串
}
fout.close();//关闭输出流
JOptionPane.showMessageDialog(null, "压缩成功", "压缩提示",JOptionPane.INFORMATION_MESSAGE);
}
//处理和HuffmanCoding类中的数据传递
public void compress(String output,String input){
try{
DataInputStream fin=new DataInputStream(new BufferedInputStream(new FileInputStream(input)));
DataOutputStream fout=new DataOutputStream(new BufferedOutputStream(new FileOutputStream(output)));
hc.createCode(hc.createHuffmanTree(hc.freq(fin)),0,0);//创建频率数组,然后huffman树,然后编码
outputFrequencies(fout);
fin.close();//关闭读到尾的文件流,准备下一次用新的流去读
outputCode(input,fout);
}catch(IOException i){
JOptionPane.showMessageDialog(null, "压缩路径错误", "错误提示",JOptionPane.ERROR_MESSAGE);
}
}
/*public static void main(String args[]){
new CompressFile().compress("C:\\Documents and Settings\\zhanghui\\桌面\\yasuo.z","C:\\Documents and Settings\\zhanghui\\桌面\\Annabell lee.txt");
}*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -