用Java写文本文件压缩和解压,采用哈夫曼编码,并给出代码注释
时间: 2024-03-26 07:41:30 浏览: 76
好的,我可以为您提供相关的Java代码,如下所示:
首先,我们需要实现哈夫曼编码的相关功能,包括建立哈夫曼树、生成哈夫曼编码表等。以下是哈夫曼编码的实现代码:
```java
import java.util.Map;
import java.util.HashMap;
import java.util.PriorityQueue;
public class HuffmanCoding {
private static class TreeNode implements Comparable<TreeNode> {
private final char ch;
private final int freq;
private final TreeNode left, right;
TreeNode(char ch, int freq, TreeNode left, TreeNode right) {
this.ch = ch;
this.freq = freq;
this.left = left;
this.right = right;
}
public boolean isLeaf() {
return left == null && right == null;
}
@Override
public int compareTo(TreeNode other) {
return Integer.compare(freq, other.freq);
}
}
public static Map<Character, String> buildHuffmanTable(String input) {
int[] freq = new int[256];
for (char ch : input.toCharArray()) {
freq[ch]++;
}
PriorityQueue<TreeNode> pq = new PriorityQueue<>();
for (char i = 0; i < freq.length; i++) {
if (freq[i] > 0) {
pq.add(new TreeNode(i, freq[i], null, null));
}
}
while (pq.size() > 1) {
TreeNode left = pq.poll();
TreeNode right = pq.poll();
pq.add(new TreeNode('\0', left.freq + right.freq, left, right));
}
Map<Character, String> huffmanTable = new HashMap<>();
buildHuffmanTable(huffmanTable, pq.peek(), "");
return huffmanTable;
}
private static void buildHuffmanTable(Map<Character, String> table, TreeNode node, String code) {
if (node.isLeaf()) {
table.put(node.ch, code);
} else {
buildHuffmanTable(table, node.left, code + '0');
buildHuffmanTable(table, node.right, code + '1');
}
}
}
```
接下来我们需要使用上述哈夫曼编码实现文本文件的压缩和解压。以下是压缩和解压的代码实现,其中对于输入的文件路径和输出的文件路径需要您自行指定:
```java
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;
public class HuffmanCompression {
public static void compress(String inputFilePath, String outputFilePath) throws IOException {
FileInputStream in = new FileInputStream(inputFilePath);
FileOutputStream out = new FileOutputStream(outputFilePath);
StringBuilder input = new StringBuilder();
int bytesRead;
byte[] buffer = new byte[1024];
while ((bytesRead = in.read(buffer)) != -1) {
for (int i = 0; i < bytesRead; i++) {
input.append((char) buffer[i]);
}
}
in.close();
Map<Character, String> huffmanTable = HuffmanCoding.buildHuffmanTable(input.toString());
StringBuilder encoded = new StringBuilder();
for (char ch : input.toString().toCharArray()) {
encoded.append(huffmanTable.get(ch));
}
while (encoded.length() % 8 != 0) {
encoded.append('0');
}
for (int i = 0; i < encoded.length(); i += 8) {
String byteStr = encoded.substring(i, i + 8);
int b = Integer.parseInt(byteStr, 2);
out.write((byte) b);
}
out.close();
}
public static void decompress(String inputFilePath, String outputFilePath) throws IOException {
FileInputStream in = new FileInputStream(inputFilePath);
FileOutputStream out = new FileOutputStream(outputFilePath);
StringBuilder encoded = new StringBuilder();
int bytesRead;
byte[] buffer = new byte[1024];
while ((bytesRead = in.read(buffer)) != -1) {
for (int i = 0; i < bytesRead; i++) {
String byteStr = Integer.toBinaryString(256 + (int) buffer[i]);
encoded.append(byteStr.substring(byteStr.length() - 8));
}
}
in.close();
Map<String, Character> huffmanTable = new HashMap<>();
for (Map.Entry<Character, String> entry : HuffmanCoding.buildHuffmanTable(encoded.toString()).entrySet()) {
huffmanTable.put(entry.getValue(), entry.getKey());
}
StringBuilder decoded = new StringBuilder();
String key = "";
for (char bit : encoded.toString().toCharArray()) {
key += bit;
if (huffmanTable.containsKey(key)) {
decoded.append(huffmanTable.get(key));
key = "";
}
}
out.write(decoded.toString().getBytes());
out.close();
}
}
```
最后,我们可以调用上述的压缩和解压函数进行压缩和解压操作,如下所示:
```java
public static void main(String[] args) throws IOException {
HuffmanCompression.compress("input.txt", "compressed.bin");
HuffmanCompression.decompress("compressed.bin", "output.txt");
}
```
注意,上述代码中的 "input.txt" 和 "output.txt" 分别是输入文件和输出文件的路径,您需要根据具体情况进行修改。
阅读全文