想要把一整套算法都整理出来,的确是件非常老心费力的事情!
但是如果一件事情不能有始有终,难免会有遗憾!
索性,继续整理!
相关链接:
BZip2与GZip有什么渊源,我这里不深究。我要说的只是,这两种算法,你在linux下都可以找到相应的操作命令。
GZip
压缩
gzip <file> 将得到压缩文件<file>.gz,同时删除文件<file>
解压缩
gzip -d <file>.gz 将得到压缩文件<file>,同时删除文件<file>.gz
BZip2与之相当,几乎没有什么差别~~
BZip2
压缩
bzip2 <file> 将得到压缩文件<file>.bz2,同时删除文件<file>
解压缩
bzip2 -d <file>.bz2 将得到压缩文件<file>,同时删除文件<file>.bz2
除了命令不同外,几乎是一样的!
再说实现。GZIP是JDK自带的算法实现,但BZip2则不曾享受这个待遇。
不过,强大的Apache坚决不会让这些个在Linux下如鱼得水的算法在Java世界中销声匿迹。Apache在
中提供了相应的实现。同时,还包括众所周知的tar、cpio、zip等算法实现,其中最为丰富的当属zip实现了!
我继续依葫芦画瓢~~~
BZip2CompressorOutputStream类用于压缩
BZip2CompressorInputStream类用于解压缩
先说压缩实现,BZip2CompressorOutputStream只有一个方法用于压缩,就是带定长的write方法。简单调用如下文所示:
1. /**
2. * 数据压缩
3. *
4. * @param is
5. * @param os
6. * @throws Exception
7. */
8. public static void
9. throws
10.
11. new
12.
13. int
14. byte data[] = new byte[BUFFER];
15. while ((count = is.read(data, 0, BUFFER)) != -1) {
16. 0, count);
17. }
18.
19. gos.finish();
20.
21. gos.flush();
22. gos.close();
23. }
与GZip实现有何差别?除了换掉了GZIPOutputStream没有任何差别。
解压缩就更不用说了,BZip2CompressorInputStream提供了一个带定长的read方法。简单调用如下文所示:
1. /**
2. * 数据解压缩
3. *
4. * @param is
5. * @param os
6. * @throws Exception
7. */
8. public static void
9. throws
10.
11. new
12.
13. int
14. byte data[] = new byte[BUFFER];
15. while ((count = gis.read(data, 0, BUFFER)) != -1) {
16. 0, count);
17. }
18.
19. gis.close();
20. }
嗯,没什么难度!
IT这行就是这样,只要你肯用心,能触类旁通,就能融会贯通!
给一个完整实现:
1. /**
2. * 2010-4-15
3. */
4. package
5.
6. import
7. import
8. import
9. import
10. import
11. import
12. import
13.
14. import
15. import
16.
17. /**
18. * BZip2工具
19. *
20. * @author <a href="mailto:zlex.dongliang@gmail.com">梁栋</a>
21. * @since 1.0
22. */
23. public abstract class
24.
25. public static final int BUFFER = 1024;
26. public static final CharSequence EXT = ".bz2";
27.
28. /**
29. * 数据压缩
30. *
31. * @param data
32. * @return
33. * @throws Exception
34. */
35. public static byte[] compress(byte[] data) throws
36. new
37. new
38.
39. // 压缩
40. compress(bais, baos);
41.
42. byte[] output = baos.toByteArray();
43.
44. baos.flush();
45. baos.close();
46.
47. bais.close();
48.
49. return
50. }
51.
52. /**
53. * 文件压缩
54. *
55. * @param file
56. * @throws Exception
57. */
58. public static void compress(File file) throws
59. true);
60. }
61.
62. /**
63. * 文件压缩
64. *
65. * @param file
66. * @param delete
67. * 是否删除原始文件
68. * @throws Exception
69. */
70. public static void compress(File file, boolean delete) throws
71. new
72. new
73.
74. compress(fis, fos);
75.
76. fis.close();
77. fos.flush();
78. fos.close();
79.
80. if
81. file.delete();
82. }
83. }
84.
85. /**
86. * 数据压缩
87. *
88. * @param is
89. * @param os
90. * @throws Exception
91. */
92. public static void
93. throws
94.
95. new
96.
97. int
98. byte data[] = new byte[BUFFER];
99. while ((count = is.read(data, 0, BUFFER)) != -1) {
100. 0, count);
101. }
102.
103. gos.finish();
104.
105. gos.flush();
106. gos.close();
107. }
108.
109. /**
110. * 文件压缩
111. *
112. * @param path
113. * @throws Exception
114. */
115. public static void compress(String path) throws
116. true);
117. }
118.
119. /**
120. * 文件压缩
121. *
122. * @param path
123. * @param delete
124. * 是否删除原始文件
125. * @throws Exception
126. */
127. public static void compress(String path, boolean delete) throws
128. new
129. compress(file, delete);
130. }
131.
132. /**
133. * 数据解压缩
134. *
135. * @param data
136. * @return
137. * @throws Exception
138. */
139. public static byte[] decompress(byte[] data) throws
140. new
141. new
142.
143. // 解压缩
144.
145. decompress(bais, baos);
146.
147. data = baos.toByteArray();
148.
149. baos.flush();
150. baos.close();
151.
152. bais.close();
153.
154. return
155. }
156.
157. /**
158. * 文件解压缩
159. *
160. * @param file
161. * @throws Exception
162. */
163. public static void decompress(File file) throws
164. true);
165. }
166.
167. /**
168. * 文件解压缩
169. *
170. * @param file
171. * @param delete
172. * 是否删除原始文件
173. * @throws Exception
174. */
175. public static void decompress(File file, boolean delete) throws
176. new
177. new
178. ""));
179. decompress(fis, fos);
180. fis.close();
181. fos.flush();
182. fos.close();
183.
184. if
185. file.delete();
186. }
187. }
188.
189. /**
190. * 数据解压缩
191. *
192. * @param is
193. * @param os
194. * @throws Exception
195. */
196. public static void
197. throws
198.
199. new
200.
201. int
202. byte data[] = new byte[BUFFER];
203. while ((count = gis.read(data, 0, BUFFER)) != -1) {
204. 0, count);
205. }
206.
207. gis.close();
208. }
209.
210. /**
211. * 文件解压缩
212. *
213. * @param path
214. * @throws Exception
215. */
216. public static void decompress(String path) throws
217. true);
218. }
219.
220. /**
221. * 文件解压缩
222. *
223. * @param path
224. * @param delete
225. * 是否删除原始文件
226. * @throws Exception
227. */
228. public static void decompress(String path, boolean delete) throws
229. new
230. decompress(file, delete);
231. }
232.
233. }
对应再来个测试用例,测试用例如下所示:
1. /**
2. * 2010-4-13
3. */
4. package
5.
6. import static
7.
8. import
9. import
10. import
11. import
12.
13. import
14.
15. /**
16. * BZip2
17. *
18. * @author <a href="mailto:zlex.dongliang@gmail.com">梁栋</a>
19. * @since 1.0
20. */
21. public class
22.
23. private String inputStr = "zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org";
24.
25. @Test
26. public final void testDataCompress() throws
27.
28. byte[] input = inputStr.getBytes();
29. "原文:\t"
30. "长度:\t"
31.
32. byte[] data = BZip2Utils.compress(input);
33. "压缩后:\t");
34. "长度:\t"
35.
36. byte[] output = BZip2Utils.decompress(data);
37. new
38. "解压缩后:\t"
39. "长度:\t"
40.
41. assertEquals(inputStr, outputStr);
42.
43. }
44.
45. @Test
46. public final void testFileCompress() throws
47.
48. new FileOutputStream("d:/f.txt");
49.
50. fos.write(inputStr.getBytes());
51. fos.flush();
52. fos.close();
53.
54. "d:/f.txt");
55.
56. "d:/f.txt.bz2");
57.
58. new File("d:/f.txt");
59.
60. new
61.
62. new
63.
64. byte[] data = new byte[(int) file.length()];
65. dis.readFully(data);
66.
67. fis.close();
68.
69. new
70. assertEquals(inputStr, outputStr);
71. }
72. }
虽然,两种算法在代码实现上几乎没有什么差别,但在压缩上想要看到效果,还真让我费了点事!
控制台输出如下所示:
引用
原文: zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org
长度: 529
压缩后:
长度: 76
解压缩后: zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org,zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org
长度: 529
529字节-->76字节!
GZIP本身不需要太长的内容,经过压缩就能体现出压缩效果,而BZip2则需要压缩很长的内容时,才能体现其压缩效果,这说明BZip2更适合大数据压缩?!
Commons Compress不仅支持BZip2算法实现,同时也支持GZip算法实现。对于GZip算法实现,与Java原生实现基本上没有什么差别。其源代码分析,仅仅是做了简单的包装。
不过有必要提及的一点是,Commons Compress为压缩(GZip和BZip2)构建了压缩算法工厂类
CompressorStreamFactory
。通过这个类可以方便的构建GZip和BZip2的输入输出流,关键字分别为“gz”和“bzip2”。
GZip
1. // GzipCompressorInputStream
2. CompressorInputStream gzipIn = new
3. "gz", is);
4.
5. // GzipCompressorOutputStream
6. CompressorOutputStream gzipOut = new
7. "gz", os);
BZip2
1. // BZip2CompressorInputStream
2. CompressorInputStream bzip2In = new
3. "bzip2", is);
4.
5. // BZip2CompressorOutputStream
6. CompressorOutputStream bzip2Out = new
7. "bzip2", os);
GZip和BZip2在算法实现步骤上基本上没有什么差别,如果有必要统一,可按上述代码实现!