一、實(shí)驗(yàn)?zāi)康?/h4>
-
深入理解HDFS工作原理和編程思想
-
使用HDFS的Java接口進(jìn)行文件的讀寫
-
使用HDFS的Java接口進(jìn)行之上傳文件
-
使用HDFS的Java接口進(jìn)行之刪除文件
二、實(shí)驗(yàn)內(nèi)容
-
HDFS的Java API接口進(jìn)行文件的讀寫操作
-
HDFS的Java API接口進(jìn)行之上傳文件操作
-
HDFS的Java API接口進(jìn)行之刪除文件操作
三、實(shí)驗(yàn)步驟
深入理解HDFS工作原理和編程思想
使用HDFS的Java接口進(jìn)行文件的讀寫
使用HDFS的Java接口進(jìn)行之上傳文件
使用HDFS的Java接口進(jìn)行之刪除文件
HDFS的Java API接口進(jìn)行文件的讀寫操作
HDFS的Java API接口進(jìn)行之上傳文件操作
HDFS的Java API接口進(jìn)行之刪除文件操作
(一)HDFS-JAVA接口之讀取文件
我們要深入探索Hadoop
的FileSystem
類,它是與Hadoop
的某一文件系統(tǒng)進(jìn)行交互的API
。
為了完成接下來的操作,你需要學(xué)習(xí)并掌握:
1.FileSystem
對象的使用,2.FSDataInputSteam
對象的使用。
FileSystem對象
要從Hadoop
文件系統(tǒng)中讀取文件,最簡單的辦法是使用java.net.URL
對象打開數(shù)據(jù)流,從中獲取數(shù)據(jù)。不過這種方法一般要使用FsUrlStreamHandlerFactory
實(shí)例調(diào)用setURLStreamHandlerFactory()
方法。不過每個Java
虛擬機(jī)只能調(diào)用一次這個方法,所以如果其他第三方程序聲明了這個對象,那我們將無法使用了。 因?yàn)橛袝r候我們不能在程序中設(shè)置URLStreamHandlerFactory
實(shí)例,這個時候咱們就可以使用FileSystem API
來打開一個輸入流,進(jìn)而對HDFS
進(jìn)行操作。
代碼如下:
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);
????}
}
FileSystem
是一個通用的文件系統(tǒng)API
,FileSystem
實(shí)例有下列幾個靜態(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è)置配置文件讀取類路徑來實(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對象
實(shí)際上,FileSystem
對象中的open()
方法返回的就是FSDataInputStream
對象,而不是標(biāo)準(zhǔn)的java.io
類對象。這個類是繼承了java.io.DataInputStream
的一個特殊類,并支持隨機(jī)訪問,由此可以從流的任意位置讀取數(shù)據(jù)。
在有了FileSystem
實(shí)例之后,我們調(diào)用open()
函數(shù)來獲取文件的輸入流。
public FSDataInputStream open(Path p)throws IOException
public abst\fract FSDataInputStream open(Path f,int bufferSize)throws IOException
了解了這些,我們在來回顧上文代碼,就能更好的理解這些方法的作用了:
編寫代碼實(shí)現(xiàn)如下功能:
使用FSDataInputStream
獲取HDFS
的/user/hadoop/
目錄下的task.txt
的文件內(nèi)容,并輸出;
預(yù)期輸出: WARN [main] - Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
怕什么真理無窮,進(jìn)一寸有一寸的歡喜。
相關(guān)代碼:
1. //啟動hadoop: start-dfs.sh
2. package step2;
3.
4. import java.io.IOException;
5. import java.io.InputStream;
6. import java.net.URI;
7.
8. import org.apache.hadoop.conf.Configuration;
9. import org.apache.hadoop.fs.FileSystem;
10. import org.apache.hadoop.fs.Path;
11. import org.apache.hadoop.io.IOUtils;
12.
13.
14. public class FileSystemCat {
15.
16. public static void main(String[] args) throws IOException {
17. /********* Begin *********/
18. Configuration config = new Configuration();
19. URI uri = URI.create("hdfs://localhost:9000/user/hadoop/task.txt");
20. FileSystem fs = FileSystem.get(uri, config);
21. InputStream in = null;
22. try {
23. in = fs.open(new Path(uri));
24. IOUtils.copyBytes(in, System.out, 2048, false);
25. } catch (Exception e) {
26. IOUtils.closeStream(in);
27. }
28. /********* End *********/
29. }
30.
31. }
(二)HDFS-JAVA接口之上傳文件
FSDataOutputStream對象
我們知道在Java
中要將數(shù)據(jù)輸出到終端,需要文件輸出流,HDFS
的JavaAPI
中也有類似的對象。 FileSystem
類有一系列新建文件的方法,最簡單的方法是給準(zhǔn)備新建的文件制定一個path
對象,然后返回一個用于寫入數(shù)據(jù)的輸出流:
public FSDataOutputStream create(Path p)throws IOException
該方法有很多重載方法,允許我們指定是否需要強(qiáng)制覆蓋現(xiàn)有文件,文件備份數(shù)量,寫入文件時所用緩沖區(qū)大小,文件塊大小以及文件權(quán)限。
注意:create()
方法能夠?yàn)樾枰獙懭肭耶?dāng)前不存在的目錄創(chuàng)建父目錄,即就算傳入的路徑是不存在的,該方法也會為你創(chuàng)建一個目錄,而不會報錯。如果有時候我們并不希望它這么做,可以先用exists()
方法先判斷目錄是否存在。
我們在寫入數(shù)據(jù)的時候經(jīng)常想要知道當(dāng)前的進(jìn)度,API
也提供了一個Progressable
用于傳遞回調(diào)接口,這樣我們就可以很方便的將寫入datanode
的進(jìn)度通知給應(yīng)用了。
package org.apache.hadoop.util;
public interface Progressable{
????public void progress();
}
編寫代碼與腳本實(shí)現(xiàn)如下功能:
在/develop/input/
目錄下創(chuàng)建hello.txt
文件,并輸入如下數(shù)據(jù): 迢迢牽牛星,皎皎河漢女。
纖纖擢素手,札札弄機(jī)杼。
終日不成章,泣涕零如雨。
河漢清且淺,相去復(fù)幾許?
盈盈一水間,脈脈不得語。
《迢迢牽牛星》
使用FSDataOutputStream
對象將文件上傳至HDFS
的/user/tmp/
目錄下,并打印進(jìn)度。
預(yù)期輸出:
?相關(guān)代碼:
shell指令:
1. mkdir /develop
2. mkdir /develop/input
3. cd /develop/input
4. touch hello.txt
5. vim hello.txt 插入數(shù)據(jù) wq 保存退出
6. start-dfs.sh
1. package step3;
2.
3.
4. import java.io.BufferedInputStream;
5. import java.io.FileInputStream;
6. import java.io.FileNotFoundException;
7. import java.io.IOException;
8. import java.io.InputStream;
9. import java.net.URI;
10. import java.io.File;
11.
12. import org.apache.hadoop.conf.Configuration;
13. import org.apache.hadoop.fs.FSDataOutputStream;
14. import org.apache.hadoop.fs.FileSystem;
15. import org.apache.hadoop.fs.Path;
16. import org.apache.hadoop.io.IOUtils;
17. import org.apache.hadoop.util.Progressable;
18.
19.
20. public class FileSystemUpload {
21.
22. public static void main(String[] args) throws IOException {
23. /********* Begin *********/
24. File localPath = new File("/develop/input/hello.txt");
25. String hdfsPath = "hdfs://localhost:9000/user/tmp/hello.txt";
26.
27. InputStream in = new BufferedInputStream(new FileInputStream(localPath));// 獲取輸入流對象
28.
29. Configuration config = new Configuration();
30.
31. FileSystem fs = FileSystem.get(URI.create(hdfsPath), config);
32.
33. long fileSize = localPath.length() > 65536 ? localPath.length() / 65536 : 1; // 待上傳文件大小
34.
35. FSDataOutputStream out = fs.create(new Path(hdfsPath), new Progressable() {
36. // 方法在每次上傳了64KB字節(jié)大小的文件之后會自動調(diào)用一次
37. long fileCount = 0;
38.
39. public void progress() {
40. System.out.println("總進(jìn)度" + (fileCount / fileSize) * 100 + "%");
41. fileCount++;
42. }
43. });
44.
45. IOUtils.copyBytes(in, out, 2048, true);// 最后一個參數(shù)的意思是使用完之后是否關(guān)閉流
46. /********* End *********/
47. }
48. }
(三)HDFS-JAVA接口之刪除文件
我們在開發(fā)或者維護(hù)系統(tǒng)時,經(jīng)常會需要列出目錄的內(nèi)容,在HDFS
的API
中就提供了listStatus()
方法來實(shí)現(xiàn)該功能。
public FileStatus[] listStatus(Path f)throws IOException
public FileStatus[] listStatus(Path f,PathFilter filter)throws IOException
public FileStatus listStatus(Path[] files)throws IOException
public FileStatus() listStatus(Path[] files,PathFilter filter)throws IOException
當(dāng)傳入?yún)?shù)是一個文件時,他會簡單的轉(zhuǎn)變成以數(shù)組方式返回長度為1
的FileStatus
對象,當(dāng)傳入?yún)?shù)是一個目錄時,則返回0
或多個FileStatus
對象,表示此目錄中包含的文件和目錄。
刪除文件
使用FileSystem
的delete()
方法可以永久性刪除文件或目錄。
public boolean delete(Path f,boolean recursive)throws IOException
如果f
是一個文件或者空目錄,那么recursive
的值可以忽略,當(dāng)recursize
的值為true
,并且p
是一個非空目錄時,非空目錄及其內(nèi)容才會被刪除(否則將會拋出IOException
異常)。
編寫代碼實(shí)現(xiàn)如下功能:
- 刪除
HDFS
的/user/hadoop/
目錄(空目錄); - 刪除
HDFS
的/tmp/test/
目錄(非空目錄); - 列出
HDFS
根目錄下所有的文件和文件夾; - 列出
HDFS
下/tmp/
的所有文件和文件夾。
預(yù)期輸出:
?相關(guān)代碼:
1. package step4;
2. import java.io.IOException;
3. import java.net.URI;
4. import org.apache.hadoop.conf.Configuration;
5. import org.apache.hadoop.fs.FileStatus;
6. import org.apache.hadoop.fs.FileSystem;
7. import org.apache.hadoop.fs.FileUtil;
8. import org.apache.hadoop.fs.Path;
9.
10. public class FileSystemDelete {
11.
12. public static void main(String[] args) throws IOException {
13. /********* Begin *********/
14. String root = "hdfs://localhost:9000/";//根目錄
15. String path = "hdfs://localhost:9000/tmp"; //要列出的目錄
16. //待刪除的兩個目錄
17. String del1 = "hdfs://localhost:9000/user/hadoop";
18. String del2 = "hdfs://localhost:9000/tmp/test";
19.
20. Configuration config = new Configuration();
21. FileSystem fs = FileSystem.get(URI.create(root),config);
22. fs.delete(new Path(del1),true);
23. fs.delete(new Path(del2),true);
24. Path[] paths = {new Path(root),new Path(path)};
25. FileStatus[] status = fs.listStatus(paths);
26. Path[] listPaths = FileUtil.stat2Paths(status);
27.
28. for(Path path1 : listPaths){
29. System.out.println(path1);
30. }
31. /********* End *********/
32. }
33. }
四、實(shí)驗(yàn)心得?
會使用HDFS的Java接口進(jìn)行文件的讀寫
會使用HDFS的Java接口進(jìn)行之上傳文件文章來源:http://www.zghlxwxcb.cn/news/detail-715767.html
會使用HDFS的Java接口進(jìn)行之刪除文件文章來源地址http://www.zghlxwxcb.cn/news/detail-715767.html
到了這里,關(guān)于云計算與大數(shù)據(jù)實(shí)驗(yàn)四 HDFS編程的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!