001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hdfs.client;
019
020import java.io.InputStream;
021import java.io.IOException;
022import java.util.List;
023
024import org.apache.hadoop.classification.InterfaceAudience;
025import org.apache.hadoop.classification.InterfaceStability;
026import org.apache.hadoop.fs.FSDataInputStream;
027import org.apache.hadoop.crypto.CryptoInputStream;
028import org.apache.hadoop.hdfs.DFSInputStream;
029import org.apache.hadoop.hdfs.ReadStatistics;
030import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
031import org.apache.hadoop.hdfs.protocol.ExtendedBlock;
032import org.apache.hadoop.hdfs.protocol.LocatedBlock;
033
034import com.google.common.base.Preconditions;
035
036/**
037 * The Hdfs implementation of {@link FSDataInputStream}.
038 */
039@InterfaceAudience.Public
040@InterfaceStability.Evolving
041public class HdfsDataInputStream extends FSDataInputStream {
042  public HdfsDataInputStream(DFSInputStream in) {
043    super(in);
044  }
045
046  public HdfsDataInputStream(CryptoInputStream in) {
047    super(in);
048    Preconditions.checkArgument(in.getWrappedStream() instanceof DFSInputStream,
049        "CryptoInputStream should wrap a DFSInputStream");
050  }
051
052  private DFSInputStream getDFSInputStream() {
053    if (in instanceof CryptoInputStream) {
054      return (DFSInputStream) ((CryptoInputStream) in).getWrappedStream();
055    }
056    return (DFSInputStream) in;
057  }
058
059  /**
060   * Get a reference to the wrapped output stream. We always want to return the
061   * actual underlying InputStream, even when we're using a CryptoStream. e.g.
062   * in the delegated methods below.
063   *
064   * @return the underlying output stream
065   */
066  public InputStream getWrappedStream() {
067    return in;
068  }
069
070  /**
071   * Get the datanode from which the stream is currently reading.
072   */
073  public DatanodeInfo getCurrentDatanode() {
074    return getDFSInputStream().getCurrentDatanode();
075  }
076
077  /**
078   * Get the block containing the target position.
079   */
080  public ExtendedBlock getCurrentBlock() {
081    return getDFSInputStream().getCurrentBlock();
082  }
083
084  /**
085   * Get the collection of blocks that has already been located.
086   */
087  public List<LocatedBlock> getAllBlocks() throws IOException {
088    return getDFSInputStream().getAllBlocks();
089  }
090
091  /**
092   * Get the visible length of the file. It will include the length of the last
093   * block even if that is in UnderConstruction state.
094   *
095   * @return The visible length of the file.
096   */
097  public long getVisibleLength() {
098    return getDFSInputStream().getFileLength();
099  }
100
101  /**
102   * Get statistics about the reads which this DFSInputStream has done.
103   * Note that because HdfsDataInputStream is buffered, these stats may
104   * be higher than you would expect just by adding up the number of
105   * bytes read through HdfsDataInputStream.
106   */
107  public ReadStatistics getReadStatistics() {
108    return getDFSInputStream().getReadStatistics();
109  }
110
111  public void clearReadStatistics() {
112    getDFSInputStream().clearReadStatistics();
113  }
114}