本節(jié)內(nèi)容
本節(jié)我們重點(diǎn)來學(xué)習(xí)HDFS系統(tǒng)提供的JavaApi,首先我們要深入探索Hadoop的FileSystem類,它是與Hadoop的某一文件系統(tǒng)進(jìn)行交互的API。

我們先來學(xué)習(xí)并掌握:1.FileSystem對象的使用,2.FSDataInputSteam對象的使用。
如果你想要在windows下調(diào)試編寫Hadoop程序,可以查看這篇帖子:
http://www.itdecent.cn/p/e037f4fd1798
<a href="http://www.itdecent.cn/p/e037f4fd1798" target="_blank"> 在Windows下開發(fā)Hadoop程序 </a>
FileSystem對象
要從Hadoop文件系統(tǒng)中讀取文件,最簡單的辦法是使用java.net.URL對象打開數(shù)據(jù)流,從中獲取數(shù)據(jù)。不過這種方法一般要使用FsUrlStreamHandlerFactory實例調(diào)用setURLStreamHandlerFactory()方法。不過每個Java虛擬機(jī)只能調(diào)用一次這個方法,所以如果其他第三方程序聲明了這個對象,那我們將無法使用了。
因為有時候我們不能在程序中設(shè)置URLStreamHandlerFactory實例,這個時候咱們就可以使用FileSystem API來打開一個輸入流,進(jìn)而對HDFS進(jìn)行操作。
接下來我們通過一個實例來學(xué)習(xí)它的用法。
首先我們在本地創(chuàng)建一個文件,然后上傳到HDFS以供測試。



接下來,我們使用FileSystem,查看咱們剛剛上傳的文件。
代碼如下:
public sattic void main(String[] args){
URI uri = URI.create("hdfs://localhost:9000/user/tmp/test.txt");
Configuration config = new Configuration();
FileSystem fs = FileSystem.get(uri, config);
InputStream in = null;
try {
in = fs.open(new Path(uri));
IOUtils.copyBytes(in, System.out, 2048, false);
} catch (Exception e) {
IOUtils.closeStream(in);
}
}
運(yùn)行成功效果如下:

上文中,FileSystem是一個通用的文件系統(tǒng)API,FileSystem實例有下列幾個靜態(tài)工廠方法用來構(gòu)造對象。
public static FileSystem get(Configuration conf)throws IOException
public static FileSystem get(URI uri,Configuration conf)throws IOException
public static FileSystem get(URI uri,Configuration conf,String user)throws IOException
Configuration對象封裝了客戶端或服務(wù)器的配置,通過設(shè)置配置文件讀取類路徑來實現(xiàn)(如:/etc/hadoop/core-site.xml)。
- 第一個方法返回的默認(rèn)文件系統(tǒng)是在
core-site.xml中指定的,如果沒有指定,就使用默認(rèn)的文件系統(tǒng)。 - 第二個方法使用給定的URI方案和權(quán)限來確定要使用的文件系統(tǒng),如果給定URI中沒有指定方案,則返回默認(rèn)文件系統(tǒng),
- 第三個方法作為給定用戶來返回文件系統(tǒng),這個在安全方面來說非常重要。
FSDataInputStream對象
實際上,FileSystem對象中的open()方法返回的就是FSDataInputStream對象,而不是標(biāo)準(zhǔn)的java.io類對象。這個類是繼承了java.io.DataInputStream的一個特殊類,并支持隨機(jī)訪問,由此可以從流的任意位置讀取數(shù)據(jù)。
在有了FileSystem實例之后,我們調(diào)用open()函數(shù)來獲取文件的輸入流。
public FSDataInputStream open(Path p)throws IOException
public abstract FSDataInputStream open(Path f,int bufferSize)throws IOException
第一個方法使用默認(rèn)的緩沖區(qū)大小為4KB。
了解了這些,我們在來回顧上文代碼,就能更好的理解這些方法的作用了:

學(xué)以致用
編寫代碼實現(xiàn)如下功能:
- 通過命令行上傳文件至HDFS的
/user/hadoop/目錄下; - 使用
FSDataInputStream獲取HDFS的/user/hadoop/目錄下的的文件內(nèi)容,并輸出;