一 、 java實現下載回顧
二 、原理解析
1. FileSystem.get(conf)解析
FileSystem.get(conf) //得到文件系統FileSystem的實例
------>
get(conf){
get(url,conf) //調用內部的get(url,conf)方法
}
------>
get(url,conf){
CACHE.get(url,conf) //調用內部的CACHE.get(url,conf)方法
}
------>
CACHE.get(url,conf) {
getInternal(url,conf,key){
fs = map.get(key) //通過map中的key得到fs的實例,map是新建的集合,所以第一次肯定拿不到
fs = createFileSystem(url,conf) //於是自己創建了一個
}
}
------>
createFileSystem(URL url,Configuration conf){
clazz = getClazz() //拿到DistrubutedFileSystem的clazz
Filesystem fs = (Filesystem)ReflectionUtils.newInstance(clazz,conf) //通過clazz反射得到Filesystem的實例
fs.initialize(url,conf) //由於反射得到,所以成員變量還沒有進行初始化,所以調用initialize方法進行初始化
return fs
}
------>
//來到了DistributeFileSystem這個類
DistributeFileSystem{
DFSClient dfs;
void initialize(URL url,Configuration conf){
this.dfs = new DFSClient(url,conf,statistics)//調用initail方法進行初始化,new DFSClient,
//將Dfsclient作爲distributFilesystem成員變量
}
}
------>
//來到了DFSClient這個類
DFSClient{
ClientProtocal namenode;
DFSClient(nameNodeuri,rocNamenode,conf,stats){
proxyInfo = NameNodeProxies.createProxyWithLossyRetryHadler(conf,nameNodeuri,
ClientProtocal.class,nuResponseToDrop) //用RPC框架工具創建一個與NN通信用的客戶端代理對象
this.namenode = proxyInfo.getProxy(); //將客戶端代理對象作爲DFSClient的成員變量
}
}
2.DFSInuptStream fs = fs.open(new Path("/1.txt"));解析
//實際上調用DistributedFileSystem的open方法
DistributedFileSystem{
DFSClient dfs;
dfs.open(path){
return new DFSInputStream(this,src,buffersize,verifyChecksum)
}
}
------>DFSInputStream給各種成員賦值
DFSInputStream(this,src,buffersize,verifyChecksum){
private dfsClient = this
private src = src
.......
private locateBlocks //對locateBlocks的賦值在openInfo方法中完成
private blockReader //對blockReader的賦值在openInfo方法中完成
openInfo(); //調用openInfo方法,對locatedBlocks賦值
}
------>
openInfo(){
......
lastBlockBeingWrittenLength = fetchLocatedBlocksAndGetLastBlockLength();//得到塊的位置信息和最後一塊的大小,
//並對locateBlocks進行賦值
}
------>
fetchLocatedBlocksAndGetLastBlockLength(){
final LocatedBlocks newInfo = dfsclient.getLocatedBlocks(src,0) //調用 getLocatedBlocks()方法,得到NN塊的信息
}
......
------>
static LocatedBlocks callGetBlockLocations(ClientProtocol namenode,String src,long start,long length){
return namenode.getBlockLocations(src,start,length) //得到NN塊的信息
}
3.
FileOutputStream out = new FileOutputStream("D:/hadoop_test/1"); //new FileOutputStream本地輸出流
4. IOUtils.copyBytes(in,out,4096,true); //進行下載操作