有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如何在Java中以位级精度读写文件

我对文件的读写有点陌生

我想以位级的精度读写文件。i、 e.读取缓冲区中与写入完全相同的位数

以下是我的尝试:

1)写入文件方法

private static final int INT_BYTES = Integer.SIZE / Byte.SIZE;
public void writeToFile(FileChannel fc, BitSet bitSet, int intId ) throws IOException 
{
  //each bitSet has a intId, first two int bytes written will have intId and bitSet.length() and rest will have content of bitSet

  int byteLenOfBitSet=(int)Math.ceil((bitSet.length/8.0)); 

  ByteBuffer bf = ByteBuffer.allocate(byteLenOfBitSet + 2*(INT_BYTES));
  bf.putInt(intId); //put the Id    
  bf.putInt(bitSet.length(); // put the bit length, it would be used during read
  bf.put(bitSet) //FIXME this is wrong, need to put bits , bf.put() put bytes               
  bf.flip();
  fc.write(bf);

}

2)从文件读取方法

   public Result readFromFile(FileChannel fc) throws IOException 
    {
      long currentPos = fc.position();
      ByteBuffer bf = ByteBuffer.allocate(2* INT_BYTES);

      if(fc.read(bf) < 0)return null;
      bf.rewind();
      int intId=bf.getInt();    //read first int as intId
      int bitLen = bf.getInt(); //read second int as bitLen to read further from file   
      int byteLen=(int)Math.ceil((bitLen/8.0));  //FIXME not so sure

      //move fc read position ahead by 2 INT_BYTES to read bitSet
      fc.position((currentPos + INT_BYTES * 2));        
      bf = ByteBuffer.allocate(byteLen);//FIXME, this is wrong, we need to somehow get bit not in bytelen , don't want unnecessarily read entire byte if there is less than 8 bit of info to read            

     if(fc.read(bf) < 0)return null;

     bf.rewind();
     BitSet readBitSet = new BitSet();

     //TODO, then read each bit from bf to a readBitSet
     // and return result with intId+readBitSet   

   }

在另一组方法中,我只能读写整数(字节级),我使用类似于上面的逻辑使它工作良好。但是,我被困在了一个水平

如果需要更多澄清,请告诉我

它可能类似于Read and write file bit by bit 但这个答案是针对Perl的,我正在寻找Java实现

编辑

我的担忧:

因为数据是这样写入文件的

2 INT_BYTES then bitSet   example: 5 3       101
2 INT_BYTES then bitSet   example: 2 10 1010111101 

我担心在尝试读取第一个bitSet时可能会读取第二个2 INT_BYTES,因此我的第一个结果位集可能是错误的。所以,想知道如何确保位级边界得到维护。i、 e.我只想在读取第一个位集时读取到第一个位集的长度


共 (1) 个答案

  1. # 1 楼答案

    This answer包括一个具有toByteArray方法的位集子类。要编写,可以从该方法获取byte[]数组,并使用ByteBuffer.put(byte[])ByteBuffer docs)。要读取,可以使用get(),然后在byte[]上循环并重建位集

    (供参考:FileChannel docs

    编辑回答你的question below

    • 我认为你可以摆脱fc.position,因为fc.readbf.getInt都提升了他们目前的地位

    • 根据this answerallocate的参数应该是您希望通过调用fc.read读取的字节数。所以2*INT_BYTES对于第一个allocate调用看起来是正确的。第二个allocate看起来也不错;不要打电话给fc.position

    • 对于byteLen,请尝试byteLen=(bitLen >> 3) + ((bitLen&0x07)?1:0)bitLen>>3除以8(2^3)并截断。所以1。。7位为零,8。。15.有一个。如果位的数量不是8的倍数,则需要再增加一个字节((bitLen&0x07)?1:0)在这种情况下为1,否则为0

    请记住,如果没有8的倍数,那么位将在末尾填充。例如,读取12位将占用流中的两个完整字节