【问题标题】:Writing Bits to a file using BitSet & FileOutputStream使用 BitSet 和 FileOutputStream 将位写入文件
【发布时间】:2014-09-09 23:43:01
【问题描述】:

在将特定位写入文件时,我遇到了一些问题。如果这与任何内容重复,我深表歉意,但我无法通过搜索找到合理的答案。

我在以下方面有很多困难:

  1. 逐位写入标头(长整型)(转换为字节数组,因此 FileOutputStream 可以利用它)到文件。

  2. 将单个位写入文件。例如,在某个阶段,我需要将一个设置为 0 的位写入文件,所以我最初的想法是使用 BitSet,但 Java 似乎将其视为空值?

    BitSet initialPadding = new BitSet();
    initialPadding.set(0, false);
    fileOutputStream.write(initialPadding.toByteArray());
    

1)

我使用必要的文件名创建了一个如下所示的 FileOutputStream:

FileOutputStream fileOutputStream = new FileOutputStream(file.getAbsolutePath());

我正在尝试创建一个“.amr”文件,因此在我执行任何位操作之前的第一步是将标头写入文件的开头。这具有以下值:

Long defaultHeader = 0x2321414d520aL;

我尝试使用以下方法将其写入文件,但我很确定它不会写入正确的结果:

fileOutputStream.write(defaultHeader.byteValue()); 

我是否使用了正确的流?我的转换完全错误吗?


2)

我有一个public BitSet fileBitSet;,它有从“.raw”文件中读取的位作为输入。我需要能够从 BitSet 中提取某些位,以便稍后将它们写入文件。我使用以下方法执行此操作:

public int getOctetPayloadHeader(int startPoint) {

    int readLength = 0;

    octetCMR = fileBitSet.get(0, 3);
    octetRES = fileBitSet.get(4, 7);

    if (octetRES.get(0, 3).isEmpty()) {

        /* Keep constructing the payload header. */

        octetFBit    = fileBitSet.get(8, 8);
        octetMode    = fileBitSet.get(9, 12);
        octetQuality = fileBitSet.get(13, 13);
        octetPadding = fileBitSet.get(14, 15);
        ... }

将这些位写入文件的最佳方法是什么?考虑到有时我可能需要在fileBitSet 中的特定偏移处写入单个位或 81 位?

【问题讨论】:

  • 问题 2(第一个问题)您正在将值 0 写入文件,根据大多数字符集,这是空字符,因此它不会出现在大多数文本编辑器中。在更高的层次上,你为什么要使用比特?使用字节会容易得多。
  • BitSet 在概念上应该是无限长并且有无限多个false 位,因此将一位设置为false 实际上应该对其没有影响。
  • 感谢您的回复,我会尝试将位对齐到字节边界并写入。

标签: java file fileoutputstream bitset


【解决方案1】:

您只能向 OutputStream 写入一件事:字节。您必须自己将位组合成字节;只有你知道如何将位组合成字节的规则。

至于这样的东西:

Long defaultHeader = 0x2321414d520aL;
fileOutputStream.write(defaultHeader.byteValue()); 

您应该仔细查看 javadocs 以了解您正在使用的方法。 byteValue() 返回单个字节;所以当然它没有做你所期望的。使用流在 oracles 教程中有很好的解释:http://docs.oracle.com/javase/tutorial/essential/io/streams.html

要写入单个位或位组,您将需要一个自定义的 OutputStream 来处理将位分组为要写入的字节。那就是通常所说的BitStream(JDK中没有这样的类);你要么自己写(我强烈推荐,这是一个很好的练习来教你有关位和字节的知识),或者在网上找到一个。

【讨论】:

  • 感谢您的回复,我仍然不确定如何有效地使用比特,但这告诉我,如果我想使用比特,我需要编写自己的 BitStream 类。
  • @GeorgeTretyakov 利用 BitSet 在内存中组合位并没有错,但只有您可以定义将其映射到流的语义;从 BitSet 到字节没有唯一的自然映射。在没有仔细检查语义的情况下随机选择现有的 JDK 类,这些类的名称暗示它们会做一些相关的事情,这注定会失败;假设类、方法或变量名称暗示任何关于它们的语义(并且假设的语义与它们的意图一致),这是一个常见的初学者错误。没有办法查看文档
猜你喜欢
  • 2014-07-29
  • 2010-11-25
  • 2019-09-06
  • 1970-01-01
  • 2021-08-16
  • 1970-01-01
  • 2020-07-12
  • 2019-11-10
  • 2013-08-22
相关资源
最近更新 更多