You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从二进制文件读取由0和1组成的字符串序列?

解决Huffman编码二进制字符串的读取问题

首先,咱们先理清你当前的问题:你把Huffman生成的0/1二进制序列以字符串形式写入了二进制文件,但用DataInputStream读取时找不到直接的readString方法。其实关键是看你写入时用了什么方法,对应就能找到读取的方式,另外我也会给你更高效的位存储方案(毕竟存字符串太浪费空间了)。

一、针对你当前写入方式的读取方案

情况1:写入时用了DataOutputStream.writeUTF()

如果你的写入代码是类似这样的:

String huffmanBinary = "101001101..."; // 你的Huffman二进制字符串
try (FileOutputStream fos = new FileOutputStream("huffman.bin");
     DataOutputStream dos = new DataOutputStream(fos)) {
    dos.writeUTF(huffmanBinary); // 用writeUTF写入字符串
} catch (IOException e) {
    e.printStackTrace();
}

那读取非常简单,DataInputStream刚好有对应的readUTF()方法,能直接还原你写入的字符串:

try (FileInputStream fis = new FileInputStream("huffman.bin");
     DataInputStream dis = new DataInputStream(fis)) {
    String binaryString = dis.readUTF(); 
    // 现在binaryString就是你之前写入的0/1序列了
    System.out.println("读取到的二进制序列:" + binaryString);
} catch (IOException e) {
    e.printStackTrace();
}

情况2:写入时直接用了getBytes()转字节写入

如果你的写入代码是把字符串转成字节数组写入的:

dos.write(huffmanBinary.getBytes(StandardCharsets.UTF_8));

那读取时需要先把文件里的所有字节读出来,再转成字符串,注意要和写入时用的编码一致:

try (FileInputStream fis = new FileInputStream("huffman.bin");
     DataInputStream dis = new DataInputStream(fis);
     ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
    byte[] buffer = new byte[1024];
    int len;
    while ((len = dis.read(buffer)) != -1) {
        baos.write(buffer, 0, len);
    }
    String binaryString = new String(baos.toByteArray(), StandardCharsets.UTF_8);
    System.out.println("读取到的二进制序列:" + binaryString);
} catch (IOException e) {
    e.printStackTrace();
}

二、更高效的Huffman存储方案(推荐)

其实把0/1序列存成字符串是很浪费空间的——每个字符占1字节,而实际每个0/1只需要1bit。比如1000位的序列,存字符串要1000字节,而用位存储只需要125字节,这才符合Huffman编码压缩的初衷。

写入时:把二进制序列转成字节存储

我们可以把每8位二进制转成一个字节,不足8位的补0(还要记录补了多少位,方便读取时还原):

String binaryString = "10100110101"; // 示例Huffman序列
int padding = 8 - (binaryString.length() % 8);
if (padding != 8) {
    // 补0到8的倍数
    binaryString += "0".repeat(padding);
}

// 把8位一组转成字节
byte[] bytes = new byte[binaryString.length() / 8];
for (int i = 0; i < bytes.length; i++) {
    String byteStr = binaryString.substring(i*8, (i+1)*8);
    bytes[i] = (byte) Integer.parseInt(byteStr, 2);
}

// 写入文件:先写补位数量,再写字节数组
try (FileOutputStream fos = new FileOutputStream("huffman_opt.bin");
     DataOutputStream dos = new DataOutputStream(fos)) {
    dos.writeInt(padding); // 记录补了多少个0
    dos.write(bytes);
} catch (IOException e) {
    e.printStackTrace();
}

读取时:把字节转回二进制序列

读取时先拿到补位数量,再把每个字节转成8位二进制字符串,最后去掉补的0:

try (FileInputStream fis = new FileInputStream("huffman_opt.bin");
     DataInputStream dis = new DataInputStream(fis)) {
    int padding = dis.readInt();
    byte[] bytes = new byte[fis.available()];
    dis.readFully(bytes);

    StringBuilder binaryBuilder = new StringBuilder();
    for (byte b : bytes) {
        // 把字节转成8位二进制,不足前面补0(注意要&0xFF避免负数问题)
        String byteStr = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
        binaryBuilder.append(byteStr);
    }

    // 去掉补的0,还原原始序列
    if (padding != 8) {
        binaryBuilder.setLength(binaryBuilder.length() - padding);
    }

    String binaryString = binaryBuilder.toString();
    System.out.println("还原的二进制序列:" + binaryString);
} catch (IOException e) {
    e.printStackTrace();
}

这样既节省了存储空间,也更符合Huffman编码的设计逻辑~

内容的提问来源于stack exchange,提问作者Roman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:38:51