) throws IOException { Block block = allocateBlock(objectPool, blockId); if (!ensureOpen()) { throw ex;
/** * Sets the length of the file in blocks. * * @param nrBlocks The number of blocks in the file. * @throws IOException if an I/O error occurs. */ public void setNrBlocks(long nrBlocks) throws IOException { if (nrBlocks == this.nrBlocks) return; super.setNrBlocks(nrBlocks); if (nrBlocks <= allocatedNrBlocks) return; allocatedNrBlocks = nrBlocks - (nrBlocks % allocationSize) + allocationSize; for (;;) { try { raf.setLength(allocatedNrBlocks * blockSize); break; } catch (ClosedChannelException ex) { // The Channel may have been inadvertently closed by another thread // being interrupted. Attempt to reopen the channel. if (!ensureOpen()) { throw ex; } // Loop back and retry the setLength(). } } }
return new MappedBlockFile(file, blockSize); } else if (ioType == IOType.EXPLICIT) { return new IOBlockFile(file, blockSize); } else { throw new IllegalArgumentException("Invalid BlockFile ioType.");
/** * Writes a buffer that was allocated by calling either {@link * #allocateBlock} or {@link #readBlock} to the specified block. The buffer * may only be written to the same block as was specified when the buffer was * allocated. * * @param block the buffer to write to the file. * @throws IOException if an I/O error occurs. */ public void writeBlock(Block block) throws IOException { long blockId = block.getBlockId(); assert(blockId >= 0) && (blockId < nrBlocks); ByteBuffer byteBuffer = block.getByteBuffer(); for (;;) { try { // Reset the position. byteBuffer.rewind(); // Write the buffer to the file. fc.write(byteBuffer, blockId * blockSize); break; } catch (ClosedChannelException ex) { // The Channel may have been inadvertently closed by another thread // being interrupted. Attempt to reopen the channel. if (!ensureOpen()) { throw ex; } // Loop back and retry the write. } } }