前面瞭解了hadoop寫檔案,讀檔案的執行過程,那麼hadoop內部是怎麼實現的呢?接下來看一下從hdfs中讀取檔案的原始碼,一起來分析一下,這樣就會更加了解hdfs
首先將hadoop/share/common中的jar以及所依賴的lib中的jar,hadoop/share/hdfs中的jar以及所依賴的lib中的jar,匯入到工程

總共59個jar包,寫一個測試類
package cn.xmf.haddop;
import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Created by Administrator on 2018/4/11.
*/
public class hdfs {
public static void main(String[] args) throws IOException {
Configuration conf = new Configuration();
conf.set("fs.defaultFS","hdfs://my01:9000/");
FileSystem fs = FileSystem.get(conf);
FSDataInputStream input = fs.open(new Path("/jdk-8u161-linux-x64.tar.gz"));
FileOutputStream output = new FileOutputStream("d:/jdk8.tgz");
IOUtils.copy(input,output);
}
}
複製程式碼
執行之後,會將之前hdfs根路徑下的jdk下載到d盤,效果如下圖

接下來重點來了將斷點打到FileSystem這一行,進入到FilegeSystem的get方法中

繼續點選get,進去

向下走,會走到

可以看出三目運算,執行CACHE.get(uri,conf),那麼進入到這個裡面看看

Cache是FileSystem的內部類,再往下看

繼續走

這裡就是根據scheme從SERVICE_FILE_SYSTEMS這個裡面拿出class,那麼hdfs對應對FileSystem的例項是什麼,繼續看一下

是DistributedFileSystem終於獲得了,下面就很簡單,就是將這個class返回,那麼在獲取FileSystem的時候,其實是根據conf中配置的fs.defaultFS來確定的哪一種FileSystem。OK到這裡剛才第一句話的原理才分析透徹,哪一句話呢?

就是圖上的這一句話:FileSystem fs = FileSystem.get(conf);
好了!到這裡先暫停一下,說一下這個FileSystem都有哪些實現類,剛才的DistributedFileSystem看名字的意思就是分散式檔案系統,說白了就是hdfs的檔案系統,問什麼它在命名的時候不叫HdfsFileSystem呢?原因就是:他願意,哈哈,你能咋地,如果這個是你開發的,你可以叫HdfsFileSystem,但是你不是,我也不是,說這麼多就是要記住DistributedFileSystem是HDFS的FileSystem。好了!看一下FileSystem都有哪些實現類

這一張圖說明他有本地檔案系統,Ftp檔案系統等等
繼續

從上圖可以看出通過class反射出Fs,因為反射出來的是成員變數都是空的,所以要進行初始化,進入初始分方法

進入到DFSClient中

DFSClient中有一個屬性叫做namenode,這個就是客戶端的代理,繼續跟蹤程式碼,這個是怎麼賦值的

進入到createNonHAProxy這個裡面

繼續走

這句話就是拿到代理物件
返回之後

這樣namenode就是代理的proxyInfo中的代理物件

初始化完成之後將代理物件放到DFSClient中,並將dfsClient放到FileSystem中,其實FileSystem裡面最終要的就是這個客戶端的代理物件,實際上就是namenode的代理物件,這樣才能進行從namenode中寫檔案和讀檔案
用一個圖說明一下這個呼叫過程,一目瞭然

好了,今天就分享了FileSystem fs = FileSystem.get(conf);
明天繼續講FSDataInputStream input = fs.open(new Path("/jdk-8u161-linux-x64.tar.gz"));