-1

Javaを使用してデータをバイナリファイルに保存したいと思います。たとえば、番号は 101 で、私のプログラムでは出力ファイルのサイズは 4 バイトです。出力ファイルに数値を 3 ビット (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_effective_data_transfer

4

3 に答える 3

2

ファイルに 1 バイト未満を書き込むことはできません。2 進数の 101 を書きたい場合は、代わりにint i = 5使用してください。os.write(i)0000 0101 という 1 バイトが書き込まれます。

于 2012-11-09T15:38:29.273 に答える
1

First off, you can't write just 3 bits to a file, memory is aligned at specific values (8, 16, 32, 64 or even 128 bit, this is compiler/platform specific). If you write smaller sizes than that, they will be expanded to match the alignment.

Secondly, the decimal number 101, written in binary is 0b01100101. the binary number 0b00000101, is decimal 5.

Thirdly, these numbers are now only 1 Byte (8 bit) long, so you can use a char instead of an int.

And last but not least, to write non-integer numbers, use os.write()

So to get to what you want, first check if you want to write 0b01100101 or 0b00000101. Change the int to a char and to the appropriate number (you can write 0b01100101 in Java). And use 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 配列を使用し、複数のビットを追加するためのより効率的な方法を含める必要があります (上記のようにビットごとではなく、配列要素bitValues全体の一部を一度に追加します)。buf

これを保存するには、 によって計算された buf から正しいバイト数を保存する必要がありますgetUsedArrayElements()

于 2012-11-10T20:14:38.800 に答える