使用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。如果我能在这里得到一些帮助来解决这个问题,我将非常高兴。非常感谢!!
答案 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。