压缩Excel文件的问题,JAVA

时间:2014-03-12 09:23:44

标签: java compression huffman-code

使用Hffman algorthim压缩excel文件时遇到一些问题。问题是我的代码似乎与.txt文件一起使用,但是当我试图压缩.xlsx或旧版本的excel时会发生错误。

首先,我这样读了我的文件:

File file = new File("fileName.xlsx");
        byte[] dataOfFile = new byte[(int) file.length()];
        DataInputStream dis = new DataInputStream(new FileInputStream(file));
        dis.readFully(dataOfFile);
        dis.close();

要检查这一点(如果一切正常)我使用此代码:

String entireFileText = new String(dataOfFile, "UTF-8");

    for(int i=0;i<dataOfFile.length;i++)
  {
  System.out.print(dataOfFile[i]);
  }

通过对.txt文件执行此操作,我得到类似这样的内容(似乎没问题):

“7210110810811132119111114108100331310721111193297114101321211111173”

但是当我在.xlsx文件上使用它时,我得到了这个,我认为连字符会在压缩后期产生错误:

“8075342006080003301165490-90122100-1245001908291671111101161011101169584121112101115934612010910832-944240-96020000000000000”......等等

无论如何,通过使用字符串,a可以将其映射到HashMap,其中我计算每个字符的频率。我有一个HashMap:

public static HashMap map;

public static boolean countHowOftenACharacterAppear(String s1) {
  String s = s1;
  for(int i = 0; i < s.length(); i++){
     char c = s.charAt(i);
     Integer val = map.get(new Character(c));
     if(val != null){
       map.put(c, new Integer(val + 1));
     }
     else{
       map.put(c,1);
     }
  }
 return true;

}

当我压缩我的字符串时,我使用:

 public static String compress(String s) {
 String c = new String();

 for(int i = 0; i < s.length(); i++)
     c = c + fromCharacterToCode.get(s.charAt(i));

 return c;

}

fromCharactertoCode是另一种类型的HashMap: public static HashMap fromCharacterToCode;

(我穿过我已建成的桌子。不要以为这就是问题)

无论如何,使用.txt文件的结果是:

“01000110110111011011110001101110011011000001000000000”......(完美)

来自.xlsx文件:

“10101110110001110null0010000null0011000nullnullnull10110000null00001101011111”......

我真的不明白为什么我会在.xlsx文件上获得nullpointers。如果我能在这里得到一些帮助来解决这个问题,我将非常高兴。非常感谢!!

1 个答案:

答案 0 :(得分:1)

在进行压缩之前,你的问题是java I / O.

首先,您并不需要DataInputStream,但请将其放在一边。然后转换为String wholeFileText,假设文件的内容是UTF-8中的文本,而.xlsx等数据文件根本不是文本,甚至在Windows上的许多文本文件也不是UTF-8。但是你似乎没有使用completeFileText,所以这可能无关紧要。如果你这样做,并且文件不是纯ASCII文本,你的压缩器将失去&#34;它的块和解压缩的输出只是压缩输入的一小部分;这通常被认为是不能令人满意的。

然后从dataOfFile中提取每个字节。 Java中的字节已签名;纯ASCII文本文件只有&#34;肯定&#34;字节0x00到0x7F(通常所有0x20到0x7E加上0x09 0x0D 0x0A),但其他一切(UTF-8文本,UTF-16文本,数据和可执行文件)将具有&#34;否定&#34;字节0x80到0xFF,以-0x80到-0x01。

您的打印输出&#34; 7210110810811132119111114108100331310721111193297114101321211111173&#34; for&#34; .txt文件&#34;几乎可以肯定的是字节序列72 = H 101 = e 108 = 1108 = 111 = o 32 =空间119 = w 111 = o 114 = r 108 = l 100 = d 33 =! 13 = CR 10 = LF 72 = H 111 = o 119 = w 32 =空间97 = a 114 = r 101 = e 32 =空间121 = y 111 = o 117 = u 3 =(ETX又名ctrl-C)(如何你有一个ctrl-C到一个文件?!或者它真的是30 = ctrl-Z?这对于Windows文本文件来说有些常见)

更熟悉.xlsx格式的人可能能够重建那个格式,但我可以告诉你正确的连字符是由于带有负值的字节,以十进制(默认情况下)打印为-128到-1。 / p>

对于通用压缩器,您不应该转换为java char&String;&#39; s;那些是为文本而设计的,并非所有文件都是文本。只需使用字节,但如果你希望它们始终为正,请使用&amp; 0xFF。