Hadoop HDFS源码学习笔记(五)

2019-03-28 13:54|来源: 网络

3、client端read数据

通过调用DFSDataInputStream的read方法,最终调用了DFSInputStream的read方法,而该类主要有两个read函数,分别为:

public synchronized int read(byte buf[], int off, int len) throws IOException

public int read(long position, byte[] buffer, int offset, int length) throws IOException

首先看第二个read即带有position参数的read,该参数指定了读取文件的位置:


为了调用该read函数我修改testRead1的代码为:

  1. byte buffer[] = new byte[4096];  
  2. in.read(10, buffer, 0, buffer.length);  

 
  1. /** 
  2.      * Read bytes starting from the specified position. 
  3.      *  
  4.      * @param position start read from this position 
  5.      * @param buffer read buffer 
  6.      * @param offset offset into buffer 
  7.      * @param length number of bytes to read 
  8.      *  
  9.      * @return actual number of bytes read 
  10.      */  
  11.     @Override  
  12.     public int read(long position, byte[] buffer, int offset, int length)  
  13.       throws IOException {  
  14.       // sanity checks   
  15.       checkOpen();  
  16.       if (closed) {  
  17.         throw new IOException("Stream closed");  
  18.       }  
  19.       failures = 0;  
  20.       long filelen = getFileLength();  
  21.       if ((position < 0) || (position >= filelen)) {  
  22.         return -1;  
  23.       }  
  24.       int realLen = length;  
  25.       if ((position + length) > filelen) {  
  26.         realLen = (int)(filelen - position);  
  27.       }  
  28.         
  29.       // determine the block and byte range within the block   
  30.       // corresponding to position and realLen   
  31.       List<LocatedBlock> blockRange = getBlockRange(position, realLen); // 先根据起始位置position和realLen得到所有相关的block   
  32.       int remaining = realLen;  
  33.       for (LocatedBlock blk : blockRange) { // 遍历所有相关的block   
  34.         long targetStart = position - blk.getStartOffset();  
  35.         long bytesToRead = Math.min(remaining, blk.getBlockSize() - targetStart); // 对于每个block,read的长度去小值   
  36.         fetchBlockByteRange(blk, targetStart,   
  37.                             targetStart + bytesToRead - 1, buffer, offset); // 从block中读取数据到buffer内   
  38.         remaining -= bytesToRead; // 变更循环变量,为读取下一个block做准备   
  39.         position += bytesToRead;  
  40.         offset += bytesToRead;  
  41.       }  
  42.       assert remaining == 0 : "Wrong number of bytes read.";  
  43.       if (stats != null) {  
  44.         stats.incrementBytesRead(realLen);  
  45.       }  
  46.       return realLen;  
  47.     }  
  48.        
  49.     @Override  
  50.     public long skip(long n) throws IOException {  
  51.       if ( n > 0 ) {  
  52.         long curPos = getPos();  
  53.         long fileLen = getFileLength();  
  54.         if( n+curPos > fileLen ) {  
  55.           n = fileLen - curPos;  
  56.         }  
  57.         seek(curPos+n);  
  58.         return n;  
  59.       }  
  60.       return n < 0 ? -1 : 0;  
  61.     }  

相关问答

更多
  • hadoop和hbase问题[2022-03-08]

    Hadoop 是一个能够对大量数据进行分布式处理的软件框架。 HBase是一个分布式的、面向列的开源数据库。 HBase在Hadoop之上提供了类似于Bigtable的能力。 HBase是Apache的Hadoop项目的子项目。 HBase不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库。 另一个不同的是HBase基于列的而不是基于行的模式。
  • hadoop hdfs目录[2022-03-28]

    移动目录的命令很简单啊,跟Linux shell的命令差不多: hdfs dfs -mv 被移动的目录A 目标目录B 直接移动就行,不知道能否解决你的问题。
  • 英语要好 只要有毅力就OK 。最好是有Java基础,因为hadoop是用java编写的,所以懂java能够帮助理解hadoop原理,当然Hadoop也提供了其他语言的api。不过看楼主是从事javaee的,所以完全没问题,至于Linux只要会基本的cd,ll就差不多了,会安装文件,也就是解压软件,不过不会也没关系,网上多了去了。其实最主要就是能够坚持
  • hadoop hdfs的问题[2021-10-30]

    最下面那张图里环境变量设置的那一行多了一个$符号 export JAVA_HOME=/usr/java/jdk1.6.0_35
  • 在使用Hadoop的过程中,很容易通过FileSystem类的API来读取HDFS中的文件内容,读取内容的过程是怎样的呢?今天来分析客户端读取HDFS文件的过程,下面的一个小程序完成的功能是读取HDFS中某个目录下的文件内容,然后输出到控制台,代码如下: [java] view plain copy public class LoadDataFromHDFS { public static void main(String[] args) throws IOException { new LoadDataF ...
  • 假设zipIn是java.util.zip.ZipInputStream ,你不应该迭代地调用getNextEntry而不是读取字节吗? I resolved this issue after doing some changes in my code. In the first part of code, I was trying to unzip all the zip files whereas I should have access the spilts. Hadoop basic, which ...
  • 实现自己的DFS接口并使其与hadoop一起使用相对简单。 您所需要的只是文件和目录的文件系统概念与您的存储之间的某种逻辑映射。 在NoSQL的情况下(如果我假设KeyValue),您应该决定如何表示目录。 您可以执行一些特殊节点,也可以将路径放入密钥。 另一个决策点 - 决定您是否关心数据位置 关于文档,我认为s3n DFS实现的来源最好从一开始。 我认为关闭的例子是由DataStax完成的Cassandra上的Hadoop http://www.datastax.com/ 另一个例子(我们稍后做的事情) ...
  • Apache Spark独立于Hadoop。 Spark允许您使用不同的数据源(包括HDFS),并且能够在独立群集中运行,或者使用现有的资源管理框架(例如,YARN,Mesos)。 因此,如果您只对Spark感兴趣,则无需安装Hadoop。 Apache Spark is independent from Hadoop. Spark allows you to use different sources of data (incl. HDFS) and is capable of running eithe ...
  • 绝对可能。 不要认为Hadoop是一个可安装的程序,它只是由一群在集群内不同节点上运行的java进程组成。 如果你使用hadoop tar ball,你可以只运行NameNode和DataNodes进程,如果你只想要HDFS。 如果您使用其他hadoop发行版(例如HDP),我认为HDFS和mapreduce来自不同的rpm软件包,但安装两个rpm软件包都有害。 如果您只需要HDFS,请再次运行NameNode和DataNodes。 Absolutely possible. Don't think Hado ...
  • Mappers从InputFormat的实现中读取输入数据。 大多数实现都来自FileInputFormat ,后者从本地计算机或HDFS读取数据。 (默认情况下,数据从HDFS读取,mapreduce作业的结果也存储在HDFS中。)当您希望从备用数据源读取数据而不是HDFS时,可以编写自定义InputFormat 。 TableInputFormat将直接从HBase读取数据记录, DBInputFormat将访问关系数据库中的数据。 您还可以想象一个系统,在特定端口上通过网络将数据流式传输到每台计算机; ...