更新時(shí)間:2021年08月12日11時(shí)56分 來(lái)源:傳智教育 瀏覽次數(shù):
本節(jié)將通過(guò)Java API來(lái)演示如何操作HDFS文件系統(tǒng),包括文件上傳與下載以及目錄操作等,具體介紹如下:
1.搭建項(xiàng)目環(huán)境
打開(kāi)Eclipse選擇FileàNewàMaven Project創(chuàng)建Maven工程,選擇“Create a simple project ”選項(xiàng),點(diǎn)擊【Next】按鈕,會(huì)進(jìn)入“New Maven Project”界面,如圖1所示。
圖1 創(chuàng)建Maven工程
在圖1中,勾選“Create a simple project(skip archetype selection)”表示創(chuàng)建一個(gè)簡(jiǎn)單的項(xiàng)目(跳過(guò)對(duì)原型模板的選擇),然后勾選“User default Workspace location”表示使用本地默認(rèn)的工作空間之后,點(diǎn)擊【Next】按鈕,如圖2所示。
圖2 創(chuàng)建Maven工程配置
在圖2中,GroupID也就是項(xiàng)目組織唯一的標(biāo)識(shí)符,實(shí)際對(duì)應(yīng)Java的包結(jié)構(gòu),這里輸入com.itcast。ArtifactID就是項(xiàng)目的唯一標(biāo)識(shí)符,實(shí)際對(duì)應(yīng)項(xiàng)目的名稱,就是項(xiàng)目根目錄的名稱,這里輸入HadoopDemo,打包方式這里選擇Jar包方式即可,后續(xù)創(chuàng)建Web工程選擇War包。
此時(shí)Maven工程已經(jīng)被創(chuàng)建好了,會(huì)發(fā)現(xiàn)在Maven項(xiàng)目中,有一個(gè)pom.xml的配置文件,這個(gè)配置文件就是對(duì)項(xiàng)目進(jìn)行管理的核心配置文件。
使用Java API操作HDFS需要用到hadoop-common、hadoop-hdfs、hadoop-client三種依賴,同時(shí)為了進(jìn)行單元測(cè)試,還要引入junit的測(cè)試包,具體代碼如文件所示。
文件 pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns=`http://maven.apache.org/POM/4.0.0` xmlns:xsi=`"http://www.w3.org/2001/XMLSchema-instance"` xsi:schemaLocation=`"http://maven.apache.org/POM/4.0.0` http://maven.apache.org/xsd/maven-4.0.0.xsd"`> <modelVersion>4.0.0</modelVersion> <groupId>com.itcast</groupId> <artifactId>HadoopDemo</artifactId> <version>0.0.1-SNAPSHOT</version> **<dependencies>** **<dependency>** **<groupId>org.apache.hadoop</groupId>** **<artifactId>hadoop-common</artifactId>** **<version>2.7.4</version>** **</dependency>** **<dependency>** **<groupId>org.apache.hadoop</groupId>** **<artifactId>hadoop-hdfs</artifactId>** **<version>2.7.4</version>** **</dependency>** **<dependency>** **<groupId>org.apache.hadoop</groupId>** **<artifactId>hadoop-client</artifactId>** **<version>2.7.4</version>** **</dependency>** **<dependency>** **<groupId>junit</groupId>** **<artifactId>junit</artifactId>** **<version>RELEASE</version>** **</dependency>** **</dependencies>** </project>``` 當(dāng)添加依賴完畢后,Hadoop相關(guān)Jar包就會(huì)自動(dòng)下載,部分Jar包如圖3所示。 ![img](uploads/course/bigData/images/3.4.2/clip_image006-1591775346489.jpg) > 圖3 成功導(dǎo)入Jar包 從圖3可以看出,所需要的Hadoop的Jar包所在路徑就是setting.xml中配置的本地倉(cāng)庫(kù)位置。 **2****.初始化客戶端對(duì)象** 首先在項(xiàng)目src文件夾下創(chuàng)建com.itcast.hdfsdemo包,并在該包下創(chuàng)建HDFS_CRUD.java文件,編寫(xiě)Java測(cè)試類,構(gòu)建Configuration和FileSystem對(duì)象,初始化一個(gè)客戶端實(shí)例進(jìn)行相應(yīng)的操作,具體代碼如文件3-2所示。 文件 HDFS_CRUD.java ```java package com.itcast.hdfsdemo; import java.io.*; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.*; import org.junit.*; public class HDFS_CRUD { FileSystem fs = null; @Before public void init() throws Exception { // 構(gòu)造一個(gè)配置參數(shù)對(duì)象,設(shè)置一個(gè)參數(shù):我們要訪問(wèn)的hdfs的URI Configuration conf = new Configuration(); // 這里指定使用的是HDFS文件系統(tǒng) **conf.set("fs.defaultFS", "hdfs://hadoop01:9000")**; // 通過(guò)如下的方式進(jìn)行客戶端身份的設(shè)置 **System.setProperty("HADOOP_USER_NAME", "root")**; // 通過(guò)FileSystem的靜態(tài)方法獲取文件系統(tǒng)客戶端對(duì)象 fs = FileSystem.get(conf); } }
在上述代碼中,@Before是一個(gè)用于在Junit單元測(cè)試框架中控制程序最先執(zhí)行的注解,這里可以保證init()方法在程序中最先執(zhí)行。
小提示:
FileSystem.get()方法從conf中的設(shè)置的參數(shù) fs.defaultFS的配置值,用來(lái)設(shè)置文件系統(tǒng)類型。如果代碼中沒(méi)有指定為fs.defaultFS,并且工程classpath下也沒(méi)有給定相應(yīng)的配置,則conf中的默認(rèn)值就來(lái)自于hadoop-common-2.7.4.jar包中的core-default.xml,默認(rèn)值為:“file:/// ”,這樣獲取的不是DistributedFileSystem實(shí)例,而是一個(gè)本地文件系統(tǒng)的客戶端對(duì)象。
3.上傳文件到HDFS
初始化客戶端對(duì)象后,接下來(lái)實(shí)現(xiàn)上傳文件到HDFS的功能。由于采用Java測(cè)試類來(lái)實(shí)現(xiàn)JavaApi對(duì)HDFS的操作,因此可以在HDFS_CRUD.java文件中添加一個(gè)testAddFileToHdfs()方法來(lái)演示本地文件上傳到HDFS的示例,具體代碼如下:
@Test public void testAddFileToHdfs() throws IOException { // 要上傳的文件所在本地路徑 Path src = new Path("D:/test.txt"); // 要上傳到hdfs的目標(biāo)路徑 Path dst = new Path("/testFile"); // 上傳文件方法 fs.copyFromLocalFile(src, dst); // 關(guān)閉資源 fs.close(); }
從上述代碼可以看出,可以通過(guò)FileSystem對(duì)象的copyFromLocalFile()方法,將本地?cái)?shù)據(jù)上傳至HDFS中。copyFromLocalFile()方法接收兩個(gè)參數(shù),第一個(gè)參數(shù)是要上傳的文件所在的本地路徑(需要提前創(chuàng)建),第二個(gè)參數(shù)是要上傳到HDFS的目標(biāo)路徑。
4.從HDFS下載文件到本地
在HDFS_CRUD.java文件中添加一個(gè)testDownloadFileToLocal()方法,來(lái)實(shí)現(xiàn)從HDFS中下載文件到本地系統(tǒng)的功能,具體代碼如下:
// 從hdfs中復(fù)制文件到本地文件系統(tǒng) @Test public void testDownloadFileToLocal() throws IllegalArgumentException, IOException { // 下載文件 fs.copyToLocalFile(new Path("/testFile"), new Path("D:/")); fs.close(); }
從上述代碼可以看出,可以通過(guò)FileSystem對(duì)象的copyToLocalFile()方法從HDFS上下載文件到本地。copyToLocalFile()方法接收兩個(gè)參數(shù),第一個(gè)參數(shù)是HDFS上的文件路徑,第二個(gè)參數(shù)是下載到本地的目標(biāo)路徑。
注意:
在Windows平臺(tái)開(kāi)發(fā)HDFS項(xiàng)目時(shí),若不設(shè)置Hadoop開(kāi)發(fā)環(huán)境,則會(huì)報(bào)以下的錯(cuò)誤:
java.io.IOException: (null) entry in command string: null chmod 0644 D:\testFile
解決方式:
(1)根據(jù)教材提示,安裝配置windows平臺(tái)hadoop(注意,配置后必須重啟電腦),運(yùn)行沒(méi)有問(wèn)題。
(2)直接使用下載的hadoop linux平臺(tái)下的壓縮包進(jìn)行解壓,然后在解壓包bin目錄下額外添加windows相關(guān)依賴文件(winutils.exe、winutils.pdb、hadoop.dll),然后進(jìn)行hadoop環(huán)境變量配置(注意,配置后必須重啟電腦),運(yùn)行同樣沒(méi)有問(wèn)題。
(3)使用FileSystem自帶的方法即使不配置windows平臺(tái)hadoop也可以正常運(yùn)行(這種方法下載后就是沒(méi)有附帶一個(gè)類似.testFile.crc的校驗(yàn)文件):
fs.copyToLocalFile(false,new Path("/testFile"), new Path("D:/"),true);
5.目錄操作
在HDFS_CRUD.java文件中添加一個(gè)testMkdirAndDeleteAndRename()方法,實(shí)現(xiàn)目錄的創(chuàng)建、刪除、重命名的功能,具體代碼如下:
// 創(chuàng)建,刪除,重命名文件 @Test public void testMkdirAndDeleteAndRename() throws Exception { // 創(chuàng)建目錄 fs.mkdirs(new Path("/a/b/c")); fs.mkdirs(new Path("/a2/b2/c2")); // 重命名文件或文件夾 fs.rename(new Path("/a"), new Path("/a3")); // 刪除文件夾,如果是非空文件夾,參數(shù)2必須給值true fs.delete(new Path("/a2"), true); }
從上述代碼可以看出,可以通過(guò)調(diào)用FileSystem的mkdirs()方法創(chuàng)建新的目錄;調(diào)用delete()方法可以刪除文件夾,delete()方法接收兩個(gè)參數(shù),第一個(gè)參數(shù)表示要?jiǎng)h除的文件夾路徑,第二個(gè)參數(shù)用于設(shè)置是否遞歸刪除目錄,其值為true或false,true表示遞歸刪除,false表示非遞歸刪除;調(diào)用rename()方法可以對(duì)文件或文件夾重命名,rename()接收兩個(gè)參數(shù),第一個(gè)參數(shù)代表需要修改的目標(biāo)路徑,第二個(gè)參數(shù)代表新的命名。
6.查看目錄中的文件信息
在HDFS_CRUD.java文件中添加一個(gè)testListFiles()方法,實(shí)現(xiàn)查看目錄中所有文件的詳細(xì)信息的功能,代碼如下:
// 查看目錄信息,只顯示文件 @Test public void testListFiles() throws FileNotFoundException, IllegalArgumentException, IOException { // 獲取迭代器對(duì)象 RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles( new Path("/"), true); while (listFiles.hasNext()) { LocatedFileStatus fileStatus = listFiles.next(); // 打印當(dāng)前文件名 System.out.println(fileStatus.getPath().getName()); // 打印當(dāng)前文件塊大小 System.out.println(fileStatus.getBlockSize()); // 打印當(dāng)前文件權(quán)限 System.out.println(fileStatus.getPermission()); // 打印當(dāng)前文件內(nèi)容長(zhǎng)度 System.out.println(fileStatus.getLen()); // 獲取該文件塊信息(包含長(zhǎng)度,數(shù)據(jù)塊,datanode的信息) BlockLocation[] blockLocations = fileStatus.getBlockLocations(); for (BlockLocation bl : blockLocations) { System.out.println("block-length:" + bl.getLength() + "--" + "block-offset:" + bl.getOffset()); String[] hosts = bl.getHosts(); for (String host : hosts) { System.out.println(host); } } System.out.println("-----------分割線-------------"); } }
在上述代碼中,可以調(diào)用FileSystem的listFiles()方法獲取文件列表,其中第一個(gè)參數(shù)表示需要獲取的目錄路徑,第二個(gè)參數(shù)表示是否遞歸查詢,這里傳入?yún)?shù)為true,表示需要遞歸查詢。
猜你喜歡:
HDFS分布式文件系統(tǒng)的優(yōu)點(diǎn)缺點(diǎn)分別是什么?
MySQL表數(shù)據(jù)導(dǎo)入到Hive文件【圖文詳解】
2021-08-06Pandas算術(shù)運(yùn)算和數(shù)據(jù)對(duì)齊【Pandas索引操作演示】
2021-07-30Jupyter Notebook功能和操作界面介紹
2021-07-30數(shù)據(jù)倉(cāng)庫(kù)的標(biāo)準(zhǔn)分層
2021-07-28數(shù)據(jù)倉(cāng)庫(kù)一般分為幾層?數(shù)據(jù)倉(cāng)庫(kù)實(shí)際分層介紹
2021-07-28Sqoop有哪些指令?Sqoop指令介紹
2021-07-26北京校區(qū)