用java语言实现Huffman压缩与解压缩文件
时间: 2024-03-20 17:40:49 浏览: 30
好的,我可以为您提供Huffman压缩与解压缩文件的Java代码。以下是实现的步骤:
## Huffman压缩
1. 读取文件并统计每个字符出现的频率
2. 用字符频率构建Huffman树
3. 遍历Huffman树并生成每个字符的编码
4. 将编码写入输出文件,并将Huffman树写入输出文件
5. 关闭输入输出流
```java
import java.io.*;
public class HuffmanCompression {
private static final int BYTE_SIZE = 8;
public static void compress(String inputFile, String outputFile) throws IOException {
FileInputStream inputStream = new FileInputStream(inputFile);
int[] frequencies = new int[256];
int totalChars = 0;
int nextByte = inputStream.read();
while (nextByte != -1) {
frequencies[nextByte]++;
totalChars++;
nextByte = inputStream.read();
}
inputStream.close();
HuffmanNode root = buildHuffmanTree(frequencies);
String[] codes = buildCodes(root);
FileOutputStream outputStream = new FileOutputStream(outputFile);
writeHeader(outputStream, frequencies);
writeCompressedData(inputStream, outputStream, codes);
outputStream.close();
}
private static HuffmanNode buildHuffmanTree(int[] frequencies) {
PriorityQueue<HuffmanNode> pq = new PriorityQueue<>();
for (int i = 0; i < frequencies.length; i++) {
if (frequencies[i] > 0) {
pq.add(new HuffmanNode((byte) i, frequencies[i]));
}
}
while (pq.size() > 1) {
HuffmanNode left = pq.poll();
HuffmanNode right = pq.poll();
HuffmanNode parent = new HuffmanNode(left, right);
pq.add(parent);
}
return pq.poll();
}
private static String[] buildCodes(HuffmanNode root) {
String[] codes = new String[256];
buildCodesHelper(codes, root, "");
return codes;
}
private static void buildCodesHelper(String[] codes, HuffmanNode node, String code) {
if (node.isLeaf()) {
codes[node.getByte()] = code;
} else {
buildCodesHelper(codes, node.getLeft(), code + "0");
buildCodesHelper(codes, node.getRight(), code + "1");
}
}
private static void writeHeader(FileOutputStream outputStream, int[] frequencies) throws IOException {
for (int i = 0; i < frequencies.length; i++) {
outputStream.write(frequencies[i]);
}
}
private static void writeCompressedData(FileInputStream inputStream, FileOutputStream outputStream, String[] codes) throws IOException {
int currentByte = 0;
int numBits = 0;
int nextByte = inputStream.read();
while (nextByte != -1) {
String code = codes[nextByte];
for (int i = 0; i < code.length(); i++) {
currentByte = currentByte << 1;
if (code.charAt(i) == '1') {
currentByte |= 1;
}
numBits++;
if (numBits == BYTE_SIZE) {
outputStream.write(currentByte);
currentByte = 0;
numBits = 0;
}
}
nextByte = inputStream.read();
}
if (numBits > 0) {
currentByte = currentByte << (BYTE_SIZE - numBits);
outputStream.write(currentByte);
}
}
private static class HuffmanNode implements Comparable<HuffmanNode> {
private byte b;
private int frequency;
private HuffmanNode left;
private HuffmanNode right;
public HuffmanNode(byte b, int frequency) {
this.b = b;
this.frequency = frequency;
}
public HuffmanNode(HuffmanNode left, HuffmanNode right) {
this.frequency = left.frequency + right.frequency;
this.left = left;
this.right = right;
}
public int getByte() {
return b & 0xff;
}
public int getFrequency() {
return frequency;
}
public boolean isLeaf() {
return left == null && right == null;
}
public HuffmanNode getLeft() {
return left;
}
public HuffmanNode getRight() {
return right;
}
@Override
public int compareTo(HuffmanNode o) {
return Integer.compare(this.frequency, o.frequency);
}
}
}
```
## Huffman解压缩
1. 读取文件头并构建Huffman树
2. 读取压缩数据,并根据Huffman树解码
3. 将解码后的数据写入输出文件
4. 关闭输入输出流
```java
import java.io.*;
public class HuffmanDecompression {
private static final int BYTE_SIZE = 8;
public static void decompress(String inputFile, String outputFile) throws IOException {
FileInputStream inputStream = new FileInputStream(inputFile);
int[] frequencies = new int[256];
for (int i = 0; i < frequencies.length; i++) {
frequencies[i] = inputStream.read();
}
HuffmanNode root = buildHuffmanTree(frequencies);
int totalChars = root.getFrequency();
FileOutputStream outputStream = new FileOutputStream(outputFile);
int numBits = 0;
int currentByte = 0;
HuffmanNode node = root;
int nextByte = inputStream.read();
while (nextByte != -1) {
for (int i = 0; i < BYTE_SIZE; i++) {
int bit = (nextByte >> (BYTE_SIZE - 1 - i)) & 1;
if (bit == 0) {
node = node.getLeft();
} else {
node = node.getRight();
}
if (node.isLeaf()) {
outputStream.write(node.getByte());
node = root;
totalChars--;
if (totalChars == 0) {
break;
}
}
}
nextByte = inputStream.read();
}
inputStream.close();
outputStream.close();
}
private static HuffmanNode buildHuffmanTree(int[] frequencies) {
PriorityQueue<HuffmanNode> pq = new PriorityQueue<>();
for (int i = 0; i < frequencies.length; i++) {
if (frequencies[i] > 0) {
pq.add(new HuffmanNode((byte) i, frequencies[i]));
}
}
while (pq.size() > 1) {
HuffmanNode left = pq.poll();
HuffmanNode right = pq.poll();
HuffmanNode parent = new HuffmanNode(left, right);
pq.add(parent);
}
return pq.poll();
}
private static class HuffmanNode implements Comparable<HuffmanNode> {
private byte b;
private int frequency;
private HuffmanNode left;
private HuffmanNode right;
public HuffmanNode(byte b, int frequency) {
this.b = b;
this.frequency = frequency;
}
public HuffmanNode(HuffmanNode left, HuffmanNode right) {
this.frequency = left.frequency + right.frequency;
this.left = left;
this.right = right;
}
public int getByte() {
return b & 0xff;
}
public int getFrequency() {
return frequency;
}
public boolean isLeaf() {
return left == null && right == null;
}
public HuffmanNode getLeft() {
return left;
}
public HuffmanNode getRight() {
return right;
}
@Override
public int compareTo(HuffmanNode o) {
return Integer.compare(this.frequency, o.frequency);
}
}
}
```
以上就是Huffman压缩与解压缩文件的Java代码,您可以根据您的需要进行修改和优化。