2014-03-12 51 views
1

我在使用Hffman algorthim壓縮excel文件時遇到了一些問題。問題是我的代碼似乎與.txt文件一起工作,但是當我嘗試壓縮.xlsx或更早版本的Excel時,會發生錯誤。壓縮Excel文件的問題,JAVA

首先,我讀我的文件是這樣的:

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(); 

要對此進行檢查(如果一切OK),我用這個代碼:

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

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

通過這樣做來一個.txt文件我得到這樣的(這似乎是OK):

「7210110810811132119111114108100331310721111193297114101321211111173」

但是,當我使用這個對.xlsx文件我得到這個,我覺得連字符使得可能在壓縮後會出現錯誤:

「8075342006080003301165490-90122100-1245001908291671111101161011101169584121112101115934612010910832-944240-96020000000000000」 ......等等

無論如何,通過使用一個字符串一個可以映射到一個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中: 公共靜態HashMap中fromCharacterToCode;

(我穿越過我的表我已經建立了Dont't覺得這是問題)

總之,使用.txt文件從這個結果是:

「01000110110111011011110001101110011011000001000000000」 ......(完美)

從.xlsx文件:

「10101110110001110null0010000null0011000nullnullnull10110000null00001101011111」 ......

我真的不明白爲什麼我會在.xlsx文件中獲取nullpointers。如果我能在這裏得到一些幫助來解決這個問題,我會非常高興。非常感謝!!

回答

1

你的問題是在進行壓縮之前的java I/O。

首先,您並不真的需要DataInputStream,但請放在一邊。然後,假設文件的內容是UTF-8文本,然後轉換爲String entireFileText,而像.xlsx這樣的數據文件根本不是文本,甚至在Windows上的許多文本文件都不是UTF-8。但你似乎並沒有使用wholeFileText,所以這可能無關緊要。如果你這樣做,並且該文件不是純ASCII的文本,你的壓縮器將會「丟失」它的大塊,並且解壓縮的輸出將只是壓縮輸入的一小部分;這通常被認爲不令人滿意。

然後從dataOfFile中提取每個字節。 Java中的字節被簽名;純ASCII文本文件只有「正」字節0x00到0x7F(通常全是0x20到0x7E加上0x09 0x0D 0x0A),但其他所有內容(UTF-8文本,UTF-16文本,數據和可執行文件) 「字節0x80到0xFF,它們以-0x80到-0x01出現。

您的打印輸出「7210110810811132119111114108100331310721111193297114101321211111173」對於「.txt文件」幾乎可以肯定是字節序列72 = H 101 = e 108 = 1108 = 111 = 32 =空間119 = 111 = 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 aka ctrl-C)你是否得到了一個ctrl-C文件?!或者它真的是30 = ctrl-Z?這對於Windows文本文件來說有點通常)

有人更熟悉.xlsx格式可能能夠重建那個,但我可以告訴你,連字符是由於負值的字節,以十進制(默認值)打印爲-128到-1。

對於通用壓縮器,您不應該將其轉換爲java char和String;這些是爲文本設計的,並不是所有文件都是文本。只需使用字節,但如果您希望它們始終如此,請使用& 0xFF進行掩碼。