public class HuffmanCode {
private Map<Byte,StringBuffer> huffmancode=new HashMap<Byte, StringBuffer>();
public static void main(String[] args) {
HuffmanCode huffmanCode=new HuffmanCode();
String inputFile="E:\\bigdata\\psdata.txt";
String outputZipFile="E:\\bigdata\\code.zip";
huffmanCode.zipFile(inputFile,outputZipFile);
String unzipFile="E:\\bigdata\\bb.txt";
huffmanCode.unzipFile(outputZipFile,unzipFile);
}
public void unzipFile(String zipFile,String dstFile){
InputStream is=null;
ObjectInputStream ois=null;
OutputStream os =null;
try {
is=new FileInputStream(zipFile);
ois=new ObjectInputStream(is);
byte[] huffmanBytes=(byte[])ois.readObject();
Map<Byte,StringBuffer> huffmap=(Map<Byte,StringBuffer>)ois.readObject();
byte[] unzipdata=unzipHuffman(huffmanBytes,huffmap);
os=new FileOutputStream(dstFile);
os.write(unzipdata);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
os.close();
ois.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void zipFile(String srcFile,String dstFile){
FileInputStream is=null;
OutputStream os = null;
ObjectOutputStream oos = null;
try {
is=new FileInputStream(srcFile);
byte[] datas=new byte[is.available()];
is.read(datas);
byte[] zipdata=huffmanZip(datas);
for(byte bts:zipdata){
System.out.print(bts+" ");
}
os=new FileOutputStream(dstFile);
oos=new ObjectOutputStream(os);
oos.writeObject(zipdata);
oos.writeObject(huffmancode);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
is.close();
oos.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public byte[] unzipHuffman(byte[] bytes,Map<Byte,StringBuffer> huffmanCodes){
StringBuffer stringBuffer=new StringBuffer();
for(int i=0;i<bytes.length;i++){
byte b=bytes[i];
boolean flag=(i==bytes.length-1);
String temp=byteToBinaryString(!flag,b);
stringBuffer.append(temp);
}
Map<String,Byte> maps=new HashMap<String,Byte>();
for(Map.Entry<Byte,StringBuffer> entry:huffmanCodes.entrySet()){
maps.put(entry.getValue().toString(),entry.getKey());
}
List<Byte> lists=new ArrayList<Byte>();
for(int i=0;i<stringBuffer.length();){
int tempIndex=1;
boolean flag=true;
Byte huffmanByte=null;
while(flag){
String temp=stringBuffer.substring(i,i+tempIndex);
huffmanByte=maps.get(temp);
if(huffmanByte==null){
tempIndex++;
}else {
flag=false;
}
}
lists.add(huffmanByte);
i+=tempIndex;
}
byte[] bs=new byte[lists.size()];
for(int i=0;i<lists.size();i++){
bs[i]=lists.get(i);
}
return bs;
}
private String byteToBinaryString(boolean flag,byte b){
int temp=b;
if(flag){
temp |= 256;
}
String str=Integer.toBinaryString(temp);
if(flag){
str=str.substring(str.length()-8);
}
return str;
}
public byte[] huffmanZip(byte[] datas){
Node node=huffmanTree(datas);
huffmancode(node,"",new StringBuffer());
Map<Byte,StringBuffer> huffmancode=getHuffmancode();
if(huffmancode.size()==0){
new Exception("获取赫夫曼编码失败");
}
StringBuffer stringBuffer =new StringBuffer();
for(byte data:datas){
stringBuffer.append(huffmancode.get(data));
}
int len;
System.out.println(stringBuffer.toString());
if(stringBuffer.length()%8==0){
len=stringBuffer.length()/8;
}else{
len=stringBuffer.length()/8+1;
}
System.out.println("len"+len);
byte[] zipbyte=new byte[len];
int index=0;
for(int i=0;i<stringBuffer.length();i+=8){
String temp;
if(i+8>stringBuffer.length()){
temp=stringBuffer.substring(i);
}else{
temp=stringBuffer.substring(i,i+8);
}
zipbyte[index]=(byte)Integer.parseInt(temp,2);
index++;
}
System.out.println("index"+index);
return zipbyte;
}
public Map<Byte, StringBuffer> getHuffmancode() {
return huffmancode;
}
public void huffmancode(Node node, String code, StringBuffer stringBuffer){
StringBuffer stringBuffer1=new StringBuffer(stringBuffer);
stringBuffer1.append(code);
if(node!=null){
if(node.getBytes()==null){
huffmancode(node.getLeft(),"0",stringBuffer1);
huffmancode(node.getRight(),"1",stringBuffer1);
}else{
huffmancode.put(node.getBytes(),stringBuffer1);
}
}
}
public Node huffmanTree(byte[] datas){
List<Node> nodes=new ArrayList<Node>();
Map<Byte,Integer> maps=new HashMap<Byte,Integer>();
for(byte data:datas){
Integer count=maps.get(data);
if(count==null){
maps.put(data,1);
}else{
maps.put(data,count+1);
}
}
for(Map.Entry<Byte,Integer> entry:maps.entrySet()){
nodes.add(new Node(entry.getKey(),entry.getValue()));
}
while(nodes.size()>1){
Collections.sort(nodes);
Node childLeft = nodes.get(0);
Node chilRight = nodes.get(1);
Integer tempCount=childLeft.getWeight()+chilRight.getWeight();
Node parent=new Node(tempCount);
parent.setLeft(childLeft);
parent.setRight(chilRight);
nodes.add(parent);
nodes.remove(childLeft);
nodes.remove(chilRight);
}
return nodes.get(0);
}
}