java - 压缩Excel文件、JAVA的问题

标签 java compression huffman-code

我在使用 Hffman 算法压缩 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-96020000000 000000”...等等

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

公共(public)静态HashMap映射;

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)静态 HashMap fromCharacterToCode;

(我正在遍历我构建的表。不认为这是问题所在)

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

“01000110110111011011110001101110011011000001000000000”...(完美)

来自 .xlsx 文件:

“10101110110001110null0010000null0011000nullnullnull10110000null00001101011111”...

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

最佳答案

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

首先,您实际上并不需要 DataInputStream,但将其放在一边。然后,您可以转换为 String WholeFileText,假设文件的内容是 UTF-8 格式的文本,而像 .xlsx 这样的数据文件根本不是文本,甚至 Windows 上的许多文本文件也不是 UTF-8。但您似乎没有使用整个文件文本,所以这可能并不重要。如果这样做,并且文件不是纯 ASCII 文本,则压缩器将“丢失”其中的 block ,并且解压缩的输出将只是压缩输入的一小部分;这通常被认为是不令人满意的。

然后从 dataOfFile 中提取每个字节。 Java中的字节是有符号的;纯 ASCII 文本文件将仅具有“正”字节 0x00 到 0x7F(通常全部 0x20 到 0x7E 加上 0x09 0x0D 0x0A),但其他所有内容(UTF-8 文本、UTF-16 文本、数据和可执行文件)将具有“负”字节 0x80 到 0xFF,显示为 -0x80 到 -0x01。

“.txt 文件”的打印输出“7210110810811132119111114108100331310721111193297114101321211111173”几乎肯定是字节序列 72=H 101=e 108=l 108=l 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=space 97=a 114=r 101=e 32=space 121=y 111=o 117=u 3=(ETX aka ctrl-C) (你是如何将 ctrl-C 放入文件中的?!还是真的 30=ctrl-Z?这对于 Windows 来说有点常见文本文件)

更熟悉 .xlsx 格式的人可能能够重建该格式,但我可以立即告诉您连字符是由于带有负值的字节造成的,以十进制(默认情况下)打印为 -128 到 -1。

对于通用压缩器,您不应该转换为 java 字符和字符串;这些文件是为文本设计的,并非所有文件都是文本。只需使用字节,但如果您希望它们始终为正,请使用 & 0xFF 进行掩码。

关于java - 压缩Excel文件、JAVA的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22346966/

相关文章:

java - 数组循环的奇怪执行

java - 使用函数从 Java 8 中总和为给定数字的数组中查找一对整数

php - 什么是 PHP 的 Memcache 中的压缩?

Java递归函数行为

c++ - 无法编写用于构建霍夫曼树的函数

java - Maven:无法执行目标 heroku:deploy-war

java - 扩展 JSP 自定义标签

c - 如何将放气/膨胀 SetDictionary 与原始放气/膨胀一起使用?

c++ - 数据长度过大的解压缓冲区会崩溃

algorithm - 仅使用霍夫曼编码的算法示例是什么?