format/src/main/java/com/github/sadikovi/riff/FileFooter.java
/**
   * Read footer from output stream.
   * Footer is assumed to be placed at the end of the stream. Seek is performed inside the method.
   * Stream is not closed after operation is complete.
   * @param in input stream
   * @param maxSize maximum stream size
   * @throws IOException
   */
Read footer from output stream.
Footer is assumed to be placed at the end of the stream. Seek is performed inside the method.
Stream is not closed after operation is complete.
@param in input stream
@param maxSize maximum stream size
@throws IOException
Read footer from output stream . Footer is assumed to be placed at the end of the stream . Seek is performed inside the method . Stream is not closed after operation is complete . @param in input stream @param maxSize maximum stream size @throws IOException
public static FileFooter readFrom(FSDataInputStream in, long maxSize) throws IOException {
    int tailOffset = 8;
    if (maxSize < tailOffset) {
      throw new IOException("Invalid stream, cannot read footer: " + maxSize + " < " + tailOffset);
    }
    ByteBuffer buffer = ByteBuffer.allocate(tailOffset);
    in.readFully(maxSize - tailOffset, buffer.array(), buffer.arrayOffset(), tailOffset);
    long meta = buffer.getLong();
    int magic = (int) (meta >>> 32);
    if (magic != Riff.MAGIC) throw new IOException("Wrong magic: " + magic + " != " + Riff.MAGIC);
    int len = (int) (meta & 0x7fffffff);
    LOG.debug("Read footer content of {} bytes", len);
    buffer = ByteBuffer.allocate(len);
    in.readFully(maxSize - tailOffset - len, buffer.array(), buffer.arrayOffset(), len);
    long numRecords = buffer.getLong();
    Statistics[] fileStats = new Statistics[buffer.getInt()];
    int i = 0;
    while (i < fileStats.length) {
      fileStats[i] = Statistics.readExternal(buffer);
      LOG.debug("Read file statistics {}", fileStats[i]);
      ++i;
    }
    return new FileFooter(fileStats, numRecords, buffer);
  }
public static FileFooter readFrom ( FSDataInputStream in , long maxSize ) throws IOException { int tailOffset = 8 ; if ( maxSize < tailOffset ) { throw new IOException ( "Invalid stream, cannot read footer: " + maxSize + " < " + tailOffset ) ; } ByteBuffer buffer = ByteBuffer . allocate ( tailOffset ) ; in . readFully ( maxSize - tailOffset , buffer . array ( ) , buffer . arrayOffset ( ) , tailOffset ) ; long meta = buffer . getLong ( ) ; int magic = ( int ) ( meta >>> 32 ) ; if ( magic != Riff . MAGIC ) throw new IOException ( "Wrong magic: " + magic + " != " + Riff . MAGIC ) ; int len = ( int ) ( meta & 0x7fffffff ) ; LOG . debug ( "Read footer content of {} bytes" , len ) ; buffer = ByteBuffer . allocate ( len ) ; in . readFully ( maxSize - tailOffset - len , buffer . array ( ) , buffer . arrayOffset ( ) , len ) ; long numRecords = buffer . getLong ( ) ; Statistics [ ] fileStats = new Statistics [ buffer . getInt ( ) ] ; int i = 0 ; while ( i < fileStats . length ) { fileStats [ i ] = Statistics . readExternal ( buffer ) ; LOG . debug ( "Read file statistics {}" , fileStats [ i ] ) ; ++ i ; } return new FileFooter ( fileStats , numRecords , buffer ) ; }
Read footer from output stream.
Read footer from output stream .
// stream size must be larger than magic + length // Read 8 bytes: magic 4 bytes and length of the header 4 bytes // reconstruct magic and written bytes // read full footer bytes // no flip - we have not reset position // read file statistics