Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 保存到二进制文件_Java_File_Binary - Fatal编程技术网

Java 保存到二进制文件

Java 保存到二进制文件,java,file,binary,Java,File,Binary,我想用java将数据保存到二进制文件中。例如,我有数字101,在我的程序中,输出文件有4个字节。如何在输出文件中仅保存三位(101)的数字? 我的程序如下所示: public static void main(String args[]) throws FileNotFoundException, IOException { int i = 101; DataOutputStream os = new DataOutputStream(new FileOutputStream("

我想用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();
}

我发现这样的情况:

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

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

其次,十进制数101,以二进制形式写入,是0b01100101。二进制数0b00000101为十进制5

第三,这些数字现在只有1字节(8位)长,因此可以使用char而不是int

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


因此,要获得所需内容,首先检查是否要写入0b01100101或0b00000101。将int更改为char和适当的数字(可以用Java编写0b01100101)。并使用os.write()

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

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));
    }
}
类位数组{
//公共字段,例如代码,在实际代码中封装
public int bits=0;//存储位的实际计数
公共字节[]buf=新字节[1];
私有void doubleBuf(){
字节[]tmp=新字节[buf.length*2];
系统阵列拷贝(buf,0,tmp,0,buf.长度);
buf=tmp;
}
私有整数数组索引(整数位数){
返回bitNum/8;
}
私有int-bitNumInArray(int-bitNum){
返回bitNum&7;//更改以buf字节为单位的位顺序
}
//返回实际使用的buf元素数,用于保存等。
//请注意,最后一个元素通常包含未使用的位。
public int getUsedArrayElements(){
返回arrayIndex(此.bits-1)+1;
}
//比特值为0表示0,非0表示1
public void setBit(字节位值,int位数值){
如果(bitNum>=this.bits | | bitNum<0)抛出新的InvalidArgumentException();

if(bitValue==0)this.buf[arrayIndex(bitNum)]&=~(byte)1这没有任何意义。2^6<101<2^7所以它至少需要7位。如果您想将数字101视为字符,那么请使用字符数组。并准备好当程序接收到不是由0和1组成的数字时崩溃,例如2、13、102等。数字“101”是一组位。我想创建一个存储二进制s的文件字符串的大小(我使用哈夫曼编码)比原始文件的大小小(UTF-8)。它不是一组位。它是一个整数。该整数的二进制表示形式是
1100101
。将其解释为
1100101
。唯一有意义的位集是
1100101
。使用正确的数据类型。我同意你的说法,我是整数。上面的代码只是一个示例。但请告诉我如何进行简单的二进制位输出?我使用哈夫曼编码,例如字母“a”的代码为1011(原始01000001(UTF-8))。我如何将其保存为4位的文件?您是否意识到,哈夫曼(例如)不存储数字,它存储二叉树导航路径。解码器也需要该树,然后执行0或1分支,直到它到达一个叶,并获得实际字节(或其他)?您不能存储不带计数的位并将其读回。如果您存储带计数的位,则其效率低于仅存储8位,即使其中一些位是“未使用的”。您不知道我的意思。我没有将整数保存到文件中,而只有一组位(仅1或0)。例如,字母“a”具有二进制表示01000001(UTF-8)但当我使用我的哈夫曼树“a”只有1011个二进制表示,我必须在输出文件中只保存4位(而不是8位)。如果你想在一个字节中存储2个东西,你需要手动从这些部分合成字节,然后写入:
os.write((val1&0x0F)问题是如何存储字节?当然,在哈夫曼算法中,字母可以有不同的大小。是的。您需要将所有可变大小的标记列表转换为(较短的)列出字节,然后将它们写入文件。当然,我做到了。我有较短的字母表示形式,例如“a'-1011”,但当我尝试安全1011归档时,输出当然至少有4个字节,而不是4位。问题是如何更改它,如何保存字节集?;)