2012-11-09 118 views
-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

+0

这没有任何意义。 2^6 <101 <2^7,所以它至少需要7位。如果您想将数字101作为字符处理,请使用char数组。并且当您的程序收到一个非0和1组成的数字时就会崩溃,例如2,13,102等 – djechlin

+0

数字'101'是位的集合。我想创建存储二进制字符串,并具有较小的大小(我使用霍夫曼编码),然后原始文件与文本(UTF-8)的文件。 – user1518451

+0

这不是一组比特。这是一个整数。该整数的二进制表示是“1100101”。唯一有点意义的解释是'1100101'。使用正确的数据类型。 – djechlin

回答

2

不能少于一个字节写入文件。如果要编写二进制数101,则执行int i = 5并使用os.write(i)。这将写入一个字节:0000 0101.

+0

你不知道我的意思。我没有保存整数编号的文件,但只有一组位(只有1或0)。例如,字母'a'具有二进制表示01000001(UTF-8),但是当我使用我的霍夫曼树'a'时,二进制表示只有1011,并且我必须在输出文件中仅在4位(不是8)中保存'a' 。 – user1518451

+1

如果你想在一个字节中存储2件事情,你需要手动组成部分中的字节,然后写入:'os.write((val1&0x0F)<< 4 |(val2&0x0f))' –

+0

问题是我如何存储字节?当然,在霍夫曼算法中,字母可以有不同的大小。 – user1518451

0

首先,你不能只写入3位到一个文件,存储器对准特定的值(8,16,32,64或甚至128位,这是编译器/平台特定)。如果你写的尺寸比这更小,它们将被扩展以匹配对齐。其次,用二进制写的十进制数101是0b01100101。二进制数字0b00000101是十进制5.第三,这些数字现在只有1字节(8位)长,因此您可以使用char而不是int。

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

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

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或长阵列,而不是字节数组,并且包括用于多个比特添加更有效的方法(添加部分bitValues一次完整的buf数组元素,而不是像上面那样一点一点的)。

要保存这一点,您需要保存buf的正确字节数,由getUsedArrayElements()计算。

相关问题