【问题标题】:Converting String of 1's and 0's to a binary file将 1 和 0 的字符串转换为二进制文件
【发布时间】:2017-07-12 01:30:42
【问题描述】:

所以我有一个包含数千个 1 和 0 的字符串,我想将它们作为二进制文件保存到文件中(这样文件大小就很小)。不幸的是,如果不遇到 NumberFormatExceptions,我无法弄清楚如何做到这一点。

我已经尝试过 Byte.parseByte 但这似乎不起作用。任何帮助将不胜感激。

 try {
        File file = new File(BINARY_FILE);
        DataOutputStream dso = new DataOutputStream(new FileOutputStream(file));
        for (int j = 0; j < bits.length(); j += 8) {
            Byte b = Byte.parseByte(bits.substring(j, j + 8));
            dso.write(b);
        }
    } catch (IOException e) {
        System.out.println("Error");
    }

【问题讨论】:

  • 显示你尝试过的代码
  • 新增,bits变量为1和0的字符串。
  • 另外,我们保证String的长度能被8整除吗?
  • 不,我们不是,这确实会导致处理字符串中的最后一个字符出现问题。这就是为什么我希望有一种方法可以写出单个位。

标签: java string binary


【解决方案1】:

如果您只想写入字节,请不要使用DataOutputStream 包装。

您还应该在完成后使用try-with-resources 关闭文件流。

解析 8 位时,需要指定基数 2,否则解析的是 base-10 数字,而不是二进制。

解析是针对有符号数字的,所以由于您使用的是 8 位无符号字节,因此您应该解析为 int,而不是 byte1

您不应使用valueOf(),而应使用parseInt()。无需获取装箱对象。

所以,你的代码应该是:

try {
    File file = new File(BINARY_FILE);
    try (FileOutputStream out = new FileOutputStream(file)) {
        for (int j = 0; j < bits.length(); j += 8) {
            int b = Integer.parseInt(bits.substring(j, j + 8), 2);
            out.write(b);
        }
    }
} catch (IOException e) {
    System.out.println("Error");
}

1parseByte(s, 2) 是有符号解析,因此它只支持"-10000000" (-12810) 和 "01111111" (12710) 之间的值)。任何以 1 开头的 8 位二进制数都会以 java.lang.NumberFormatException: Value out of range. Value:"11111111" Radix:2 失败

【讨论】:

  • 如果使用 8 位字节,使用 32 位 int 似乎有点低效,只是因为符号。
  • @DM write() 采用int 作为参数,即使它只使用低8 位,所以无论如何它都会被转换为int,无论你解析为@987654340 @、shortint。无法解析到没有错误的字节,所以还不如解析到int,因为这就是方法想要的。
  • 这似乎可行,但如果有更好的东西会继续尝试和改进。
  • @Andreas 哦,哇,我没有意识到write 忽略了大部分传入的整数。我认为这就是writeByte 的用途。这就是我假设的结果。
  • 你不应该使用 2 的基数吗?
【解决方案2】:

我想解决一个尚未解决的问题:如何处理奇数位。

您不能将单个位写入文件,只能写入字节。文件大小始终是完整字节,即使 Java 可以处理文件大小只有一个字节的文件,您的文件系统也不能。

为了输出可能是也可能不是全 8 的最后几位数字,您可以执行以下操作:

    for (int j = 0; j < bits.length(); j += 8) {
        int b;
        if (j + 8 < bits.length())
        {
            b = Integer.parseInt(bits.substring(j, j + 8), 2);
        }
        else
        {
            b = Integer.parseInt(bits.substring(j), 2);
        }
        dso.write(b);
    }

现在您的 substring 不会超出字符串的末尾。

至于如何区分以“00001111”结尾的字符串和以“1111”结尾的字符串(它们具有相同的字节值),也许您可​​以在文件的开头写一个带有值bits.length % 8。这将使您知道如何处理最后一个字节。例如,如果它是 6,那么您知道 1111 确实是“001111”而不是“1111”。如果是4,那就真的是“1111”了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-01
    • 2017-04-25
    • 1970-01-01
    • 1970-01-01
    • 2013-03-24
    • 2019-11-24
    • 1970-01-01
    相关资源
    最近更新 更多