package HRJ;
import java.io.*;
import java.util.ArrayList;
import java.util.ArrayList;
public class Handle {
static void Compress(String fileName){
File file = new File(fileName);
ArrayList<String> fileArrayList = new ArrayList<>();
fileArrayList = Assistance.getAllFilePaths(file,fileArrayList);
String target = Assistance.gettargetname(fileName);
File tf = new File(target);
//如果是文件夹
if(file.isDirectory()) {
try {
tf.createNewFile();
} catch (IOException e) {
e.printStackTrace();
return;
}
try {
ArrayList<Unit> biao = new ArrayList<>();
ArrayList<HCode> code;
Assistance.readFileByBytes(fileName, biao);//读取所有文件获得字符哈夫曼编码表
ArrayList<Unit> bb = new ArrayList<>();
for(int i = 0;i<biao.size();i++){
Unit help = new Unit(biao.get(i).content, biao.get(i).quantity);
bb.add(help);
}
if(biao.size()==0)
code = null;
else {
Haffmantree tree = new Haffmantree(bb);
Code c = new Code(tree);
code = c.tabel;
}
File targetfile;
FileOutputStream fos = new FileOutputStream(target);
BufferedOutputStream bos = new BufferedOutputStream(fos);
if(biao.size()==0) //为了之后读取的时候区别到底是0还是256溢出成了0
bos.write(0);
else bos.write(1);
bos.write(biao.size());
int i;
String binary = "";
int By;
//写入字符频率表
for(i = 0;i<biao.size();i++){
int ch = biao.get(i).content;
bos.write((byte)ch);
binary = Integer.toBinaryString(biao.get(i).quantity);
bos.write(binary.length());
while (binary.length()>8){
By = ((binary.charAt(0) - 48) * 128
+ (binary.charAt(1) - 48) * 64 + (binary.charAt(2) - 48) * 32
+ (binary.charAt(3) - 48) * 16 + (binary.charAt(4) - 48) * 8
+ (binary.charAt(5) - 48) * 4 + (binary.charAt(6) - 48) * 2
+ (binary.charAt(7) - 48));
bos.write((byte)By);
binary = binary.substring(8);
}
int two = 1;
By = 0;
for(int zero = binary.length();zero>0;zero--) {
By=By+(binary.charAt(zero-1)-48)*two;
two*=2;
}
bos.write((byte)By);
}
int filenamelength;
for(String f:fileArrayList){
//写入文件夹
if((targetfile = new File(f)).isDirectory()){
filenamelength = targetfile.getAbsolutePath().length();
bos.write(filenamelength);
for(int g = 0; g<filenamelength;g++){
bos.write(targetfile.getAbsolutePath().charAt(g));
}
}
//写入文件
else {
filenamelength = targetfile.getAbsolutePath().length();
bos.write(filenamelength);
for(int g = 0; g<filenamelength;g++){
bos.write(targetfile.getAbsolutePath().charAt(g));
}
Long filelength = targetfile.length();
String b = "";
b = Long.toBinaryString(filelength);
bos.write(b.length());//文件长度二进制码的长度
FileInputStream fis = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(fis);
if(filelength==0L){//文件长度为零
bos.write(0);
}
byte[] B = new byte[1024000000];
int bytelength, temp;
while ((bytelength = bis.read(B))!=-1) {
for (i = 0; i < bytelength; i++) {
temp = 0|(B[i]&0x000000ff);
b+=code.get(temp).code;
while (b.length()>8) {
By = (((b.charAt(0) - 48) << 7)
+ ((b.charAt(1) - 48) << 6) + ((b.charAt(2) - 48) << 5)
+ ((b.charAt(3) - 48) << 4) + ((b.charAt(4) - 48) << 3)
+ ((b.charAt(5) - 48) << 2) + ((b.charAt(6) - 48) << 1)
+ (b.charAt(7) - 48));
bos.write((byte) By);//第一个By为文件长度
b = b.substring(8);
}
}
}
while (b.length()%8!=0){
b+="0";//补零
}
By = (((b.charAt(0) - 48) << 7)
+ ((b.charAt(1) - 48) << 6) + ((b.charAt(2) - 48) << 5)
+ ((b.charAt(3) - 48) << 4) + ((b.charAt(4) - 48) << 3)
+ ((b.charAt(5) - 48) << 2) + ((b.charAt(6) - 48) << 1)
+ (b.charAt(7) - 48));
if(targetfile.length()!=0) {
bos.write((byte) By);
}
}
}
bos.close();
}
catch (IOException e){
e.printStackTrace();
return;
}
}
//如果是单个文件
else if(file.isFile()){
ArrayList<Unit> a = new ArrayList<>();
Assistance.readFileByBytes(fileName,a);//读取文件
ArrayList<Unit> biao = new ArrayList<>();
for(int i = 0;i<a.size();i++){
Unit help = new Unit(a.get(i).content, a.get(i).quantity);
biao.add(help);
}
Haffmantree tree = new Haffmantree(a);
Code c = new Code(tree);
ArrayList<HCode> code = c.tabel;
String fn = fileName.substring(fileName.lastIndexOf("."));
String b = new String();
int By = 0;
try {
tf.createNewFile();
}
catch (IOException e){
e.printStackTrace();
}
String binary = new String();
InputStream in = null;
try {
FileOutputStream fos = new FileOutputStream(target);
BufferedOutputStream bos = new BufferedOutputStream(fos);
in = new FileInputStream(file);
for(int g = 0; g<fn.length();g++){
bos.write(fn.charAt(g));
}
bos.write(' ');//标志着文件格式结束
int tempbyte=0, i;
//写入字符频率表
bos.write(biao.size());
for(i = 0;i<biao.size();i++){
bos.write((int)biao.get(i).content);
binary = Integer.toBinaryString(biao.get(i).quantity);
bos.write(binary.length()); //字符频率的二进制码的�