-1

我想使用 java 将数据保存到二进制文件中。例如,我有数字 101,在我的程序中,输出文件有 4 个字节。如何在输出文件中仅将数字保存为三位(101)?我的程序如下所示:

public static void main(String args[]) throws FileNotFoundException, IOException {
    int i = 101;
    DataOutputStream os = new DataOutputStream(new FileOutputStream("file"));
    os.writeInt(i);
    os.close();
}

我发现了类似的东西:http: //www.developer.nokia.com/Community/Wiki/Bit_Input/Output_Stream_utility_classes_for_efficient_data_transfer

4

3 回答 3

2

您不能向文件写入少于一个字节。如果你想写二进制数 101 然后做int i = 5os.write(i)改用。这将写入一个字节:0000 0101。

于 2012-11-09T15:38:29.273 回答
1

首先,您不能只将 3 位写入文件,内存以特定值对齐(8、16、32、64 甚至 128 位,这是编译器/平台特定的)。如果您编写的尺寸小于该尺寸,它们将被扩展以匹配对齐方式。

其次,十进制数101,用二进制写成0b01100101。二进制数 0b00000101 是十进制 5。

第三,这些数字现在只有 1 个字节(8 位)长,因此您可以使用 char 代替 int。

最后但并非最不重要的一点是,要编写非整数,请使用os.write()

所以要得到你想要的,首先检查你是想写0b01100101还是0b00000101。将 int 更改为 char 并更改为适当的数字(您可以在 Java 中编写 0b01100101)。并使用 os.write()

于 2012-11-09T15:45:12.897 回答
0

一个非常幼稚的实现,我希望它可以帮助您掌握这个想法。也未经测试,可能包含一个错误等...

class BitArray {
  // public fields for example code, in real code encapsulate
  public int bits=0; // actual count of stored bits
  public byte[] buf=new byte[1];

  private void doubleBuf() {
    byte [] tmp = new byte[buf.length * 2];
    System.arraycopy(buf, 0, tmp, 0, buf.length);
    buf = tmp;
  }

  private int arrayIndex(int bitNum) {
    return bitNum / 8;
  }

  private int bitNumInArray(int bitNum) {
    return bitNum & 7; // change to change bit order in buf's bytes
  }

  // returns how many elements of buf are actually in use, for saving etc.
  // note that last element usually contains unused bits.
  public int getUsedArrayElements() {
    return arrayIndex(this.bits-1) + 1;
  }

  // bitvalue is 0 for 0, non-0 for 1
  public void setBit(byte bitValue, int bitNum) { 
    if (bitNum >= this.bits || bitNum < 0) throw new InvalidArgumentException();
    if (bitValue == 0) this.buf[arrayIndex(bitNum)] &= ~((byte)1 << bitNumInArray(bitNum));
    else this.buf[arrayIndex(bitNum)] |= (byte)1 << bitNumInArray(bitNum);
  }

  public void addBit(int bitValue) {
    // this.bits is old bit count, which is same as index of new last bit
    if (this.buf.length <= arrayIndex(this.bits)) doubleBuf(); 
    ++this.bits;
    setBit(bitValue, this.bits-1);
  }

  int readBit(int bitNum) {  // return 0 or 1
    if (bitNum >= this.bits || bitNum < 0) throw new InvalidArgumentException();
    byte value = buf[arrayIndex(bitNum)] & ((byte)1 << bitNumInArray(bitNum));
    return (value == 0) ? 0 : 1;
  }

  void addBits(int bitCount, int bitValues) {
    for (int num = bitCount - 1 ; num >= 0 ; --num) {
      // change loop iteration order to change bit order of bitValues
      addBit(bitValues & (1 << num));
    }
}

对于有效的解决方案,它应该使用 int 或 long 数组而不是 byte 数组,并包括更有效的多位相加方法(一次添加bitValues整个buf数组元素的一部分,而不是像上面那样逐位添加)。

要保存它,您需要从 buf 中保存正确数量的字节,由getUsedArrayElements().

于 2012-11-10T20:14:38.800 回答