예제 #1
0
  private void checkAndAdvanceBlockInStream() throws IOException {
    if (mCurrentBlockLeft == 0) {
      if (mCurrentBlockInStream != null) {
        mCurrentBlockInStream.close();
      }

      mCurrentBlockIndex = getCurrentBlockIndex();
      mCurrentBlockInStream = BlockInStream.get(FILE, READ_TYPE, mCurrentBlockIndex);
      mCurrentBlockLeft = BLOCK_CAPACITY;
    }
  }
예제 #2
0
  @Override
  public int read(byte[] b, int off, int len) throws IOException {
    if (b == null) {
      throw new NullPointerException();
    } else if (off < 0 || len < 0 || len > b.length - off) {
      throw new IndexOutOfBoundsException();
    } else if (len == 0) {
      return 0;
    }

    int tOff = off;
    int tLen = len;

    while (tLen > 0 && mCurrentPosition < FILE_LENGTH) {
      checkAndAdvanceBlockInStream();

      int tRead = mCurrentBlockInStream.read(b, tOff, tLen);

      mCurrentPosition += tRead;
      mCurrentBlockLeft -= tRead;
      tLen -= tRead;
      tOff += tRead;
    }

    return len - tLen;
  }
예제 #3
0
  /**
   * Return the {@code InStream} of this file based on the specified read type. If it has no block,
   * return an {@code EmptyBlockInStream}; if it has only one block, return a {@code BlockInStream}
   * of the block; otherwise return a {@code FileInStream}.
   *
   * @param readType the InStream's read type
   * @return the InStream
   * @throws IOException
   */
  public InStream getInStream(ReadType readType) throws IOException {
    if (readType == null) {
      throw new IOException("ReadType can not be null.");
    }

    if (!isComplete()) {
      throw new IOException("The file " + this + " is not complete.");
    }

    if (isDirectory()) {
      throw new IOException("Cannot open a directory for reading.");
    }

    ClientFileInfo fileStatus = getUnCachedFileStatus();
    List<Long> blocks = fileStatus.getBlockIds();

    if (blocks.size() == 0) {
      return new EmptyBlockInStream(this, readType, mTachyonConf);
    }

    if (blocks.size() == 1) {
      return BlockInStream.get(this, readType, 0, mUFSConf, mTachyonConf);
    }

    return new FileInStream(this, readType, mUFSConf, mTachyonConf);
  }
예제 #4
0
  @Override
  public void close() throws IOException {
    if (!mClosed && mCurrentBlockInStream != null) {
      mCurrentBlockInStream.close();
    }

    mClosed = true;
  }
예제 #5
0
  @Override
  public void seek(long pos) throws IOException {
    if (mCurrentPosition == pos) {
      return;
    }
    if (pos < 0) {
      throw new IOException("pos is negative: " + pos);
    }

    if ((int) (pos / BLOCK_CAPACITY) != mCurrentBlockIndex) {
      mCurrentBlockIndex = (int) (pos / BLOCK_CAPACITY);
      if (mCurrentBlockInStream != null) {
        mCurrentBlockInStream.close();
      }
      mCurrentBlockInStream = BlockInStream.get(FILE, READ_TYPE, mCurrentBlockIndex);
    }
    mCurrentBlockInStream.seek(pos % BLOCK_CAPACITY);
    mCurrentPosition = pos;
    mCurrentBlockLeft = BLOCK_CAPACITY - (pos % BLOCK_CAPACITY);
  }
예제 #6
0
  @Override
  public int read() throws IOException {
    if (mCurrentPosition >= FILE_LENGTH) {
      return -1;
    }

    checkAndAdvanceBlockInStream();

    mCurrentPosition++;
    mCurrentBlockLeft--;
    return mCurrentBlockInStream.read();
  }
예제 #7
0
  @Override
  public long skip(long n) throws IOException {
    if (n <= 0) {
      return 0;
    }

    long ret = n;
    if (mCurrentPosition + n >= FILE.length()) {
      ret = FILE.length() - mCurrentPosition;
      mCurrentPosition += ret;
    } else {
      mCurrentPosition += n;
    }

    int tBlockIndex = (int) (mCurrentPosition / BLOCK_CAPACITY);
    if (tBlockIndex != mCurrentBlockIndex) {
      if (mCurrentBlockInStream != null) {
        mCurrentBlockInStream.close();
      }

      mCurrentBlockIndex = tBlockIndex;
      mCurrentBlockInStream = BlockInStream.get(FILE, READ_TYPE, mCurrentBlockIndex);
      long shouldSkip = mCurrentPosition % BLOCK_CAPACITY;
      long skip = mCurrentBlockInStream.skip(shouldSkip);
      mCurrentBlockLeft = BLOCK_CAPACITY - skip;
      if (skip != shouldSkip) {
        throw new IOException(
            "The underlayer BlockInStream only skip " + skip + " instead of " + shouldSkip);
      }
    } else {
      long skip = mCurrentBlockInStream.skip(ret);
      if (skip != ret) {
        throw new IOException(
            "The underlayer BlockInStream only skip " + skip + " instead of " + ret);
      }
    }

    return ret;
  }