文件的压缩
/** * 根据传入的文件,统计每个字节出现的次数 * @param path文件的路径 * @returnint数组 */public int[] fileByteCount(String path){//存储文件中每个字节出现的次数try{FileInputStream fis=new FileInputStream(path);BufferedInputStream bis=new BufferedInputStream(fis);while(fis.available()>0){//文件是否读完int i=fis.read();byteCount[i]++;//用数组存储每个字节出现的次数}fis.close();bis.close();}catch(Exception ef){ef.printStackTrace();}return byteCount;}
/** * 创建最优二叉树的方法 * @param arr:传入的数组 * @param TreeNode:返回根结点 */public TreeNode createHuffman(int[] arr){//实例化一个优先队列对象PriorityQueue<TreeNode> queue = new PriorityQueue<TreeNode>(11,new MyComparator());TreeNode root=null;//遍历数组,将数组元素构建成结点,并添加到队列中for (int i=0;i<arr.length;i++){if(arr[i]!=0){//创建结点,结点值不为0TreeNode node = new TreeNode(i,arr[i]);//将结点添加到队列中queue.add(node);}}//遍历队列,每次取出两个最小元素作为叶子结点,它们的和作为父结点建立二叉树,//并从队列中删除这两个元素,同时把它们的父结点添加到队列中while(queue.size()>1){//同时取两个最小元素TreeNode node1 = queue.poll();TreeNode node2 = queue.poll();//根据取得的元素创建父结点TreeNode fnode = new TreeNode(0,node1.getZijie()+node2.getZijie());//建立引用关系fnode.setLeft(node1);fnode.setRight(node2);node1.setParent(fnode);node2.setParent(node2);//将父结点添加到队列中queue.add(fnode);}root =queue.peek();return root;}
/** * 根据根结点创建哈夫曼编码 * 规则:左子结点为:1,右子结点为:0 * @param root:根结点 */public void createCode(TreeNode root,String code){//首先是确定各结点的路径//得到子结点TreeNode left = root.getLeft();TreeNode right = root.getRight();//打印叶子节点if (left==null&&right==null){System.out.println(root.getObj()+"的编码为:"+code);//byteCode 的下标是字节,值为其哈夫曼编码byteCode[(Integer)root.getObj()]=code;}if (left!=null){//递归createCode(left,code+"0");}if (right!=null){//递归createCode(right,code+"1");}}
/** * 把源文件和huffman编码写入文件中去 * @param path源文件路径 * @param path1要写入的文件路径 * @param strhuffman编码的String数组 */public void writeToFile(String path,String path1,String []str){try{FileOutputStream fos = new FileOutputStream(path1);DataOutputStream Dos = new DataOutputStream(fos);// 创建输出流for (int k = 0; k< str.length; k++) {if (str[k] != null){ Dos.writeInt(k);Dos.writeInt(str[k].length());}else{str[k]="";Dos.writeInt(k);Dos.writeInt(0);}}//先把编码写入文件int count=0;//记录中转的字符个数int i=0;//第i个字节String writes="";String tranString ="";String waiteString ;while(i<256||count>=8){//等待的字符大于8if(count>=8){waiteString="";//讲writes前8位取出for (int t = 0; t < 8; t++) {waiteString = waiteString + writes.charAt(t);}// 将writes前八位去掉if (writes.length() > 8) {tranString = "";for (int t = 8; t < writes.length(); t++) {tranString = tranString + writes.charAt(t);}writes = "";writes = tranString;}else {//刚好只有8位writes = "";}count = count - 8;// 写出一个8位的字节int intw = changeString(waiteString);// 得到String转化为int// 写入文件Dos.writeInt(intw);}else if(count<8){// 得到第i个编码信息等待写入if (str[i]!= null ) {count = count + str[i].length();if(str[i].length()!=0){}writes = writes + str[i];i++;}}}// 把所有编码没有足够8的整数倍的String补0使得足够8的整数倍,在写入if (count > 0&&count<8) {waiteString = "";// 清空要转化的编码int buzero=0;for (int t = 0; t < 8; t++) {if (t < writes.length()) {waiteString = waiteString + writes.charAt(t);} else {waiteString = waiteString + "0";//补了多少个0buzero++;}}Dos.writeInt(changeString(waiteString));Dos.writeInt(buzero);}try{// 将源文件中的所有byte转化为01字符串,写入压缩文件FileInputStream fis = new FileInputStream(path);BufferedInputStream bis = new BufferedInputStream(fis);count =0;writes="";tranString ="";int idata=bis.read();while(bis.available()>0||count>=8){//如果缓冲区等待写入的字符超过8if(count>=8){waiteString="";for (int t = 0; t < 8; t++) {waiteString = waiteString + writes.charAt(t);}// 将前八位删掉if (writes.length() > 8) {tranString = "";for (int t = 8; t < writes.length(); t++) {tranString = tranString + writes.charAt(t);}writes = "";writes = tranString;} else {writes = "";}count = count - 8;// 写出一个8位的字节int intw = changeString(waiteString);Dos.writeInt(intw);}else {// 如果不够8位,就继续取下一个字节count = count + str[idata].length();writes = writes + str[idata];idata = bis.read();}}count = count + str[idata].length();writes = writes + str[idata];// 把count剩下的写入int endsint = 0;if (count > 0) {waiteString = "";// 清空要转化的码for (int t = 0; t < 8; t++) {if (t < writes.length()) {waiteString = waiteString + writes.charAt(endsint);} else {waiteString = waiteString + '0';endsint++;}}Dos.writeInt(changeString(waiteString));// 写入所补的0;Dos.writeInt(endsint);System.out.println(endsint);Dos.flush();}fis.close();bis.close();fos.close();Dos.close();}catch(Exception ef){ef.printStackTrace();}}catch(Exception ef){ef.printStackTrace();}}
?
<!--EndFragment-->