教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

如何使用Java API操作HDFS系統(tǒng)?

更新時間:2021年08月12日11時56分 來源:傳智教育 瀏覽次數(shù):

本節(jié)將通過Java API來演示如何操作HDFS文件系統(tǒng),包括文件上傳與下載以及目錄操作等,具體介紹如下:

1.搭建項目環(huán)境

打開Eclipse選擇FileàNewàMaven Project創(chuàng)建Maven工程,選擇“Create a simple project ”選項,點擊【Next】按鈕,會進入“New Maven Project”界面,如圖1所示。

使用Java API操作HDFS

圖1 創(chuàng)建Maven工程

在圖1中,勾選“Create a simple project(skip archetype selection)”表示創(chuàng)建一個簡單的項目(跳過對原型模板的選擇),然后勾選“User default Workspace location”表示使用本地默認的工作空間之后,點擊【Next】按鈕,如圖2所示。

使用Java API操作HDFS

圖2 創(chuàng)建Maven工程配置

在圖2中,GroupID也就是項目組織唯一的標識符,實際對應Java的包結構,這里輸入com.itcast。ArtifactID就是項目的唯一標識符,實際對應項目的名稱,就是項目根目錄的名稱,這里輸入HadoopDemo,打包方式這里選擇Jar包方式即可,后續(xù)創(chuàng)建Web工程選擇War包。

此時Maven工程已經(jīng)被創(chuàng)建好了,會發(fā)現(xiàn)在Maven項目中,有一個pom.xml的配置文件,這個配置文件就是對項目進行管理的核心配置文件。

使用Java API操作HDFS需要用到hadoop-common、hadoop-hdfs、hadoop-client三種依賴,同時為了進行單元測試,還要引入junit的測試包,具體代碼如文件所示。

文件 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>```

當添加依賴完畢后,Hadoop相關Jar包就會自動下載,部分Jar包如圖3所示。

![img](uploads/course/bigData/images/3.4.2/clip_image006-1591775346489.jpg)

&gt; 圖3   成功導入Jar包

從圖3可以看出,所需要的Hadoop的Jar包所在路徑就是setting.xml中配置的本地倉庫位置。

**2****.初始化客戶端對象**

首先在項目src文件夾下創(chuàng)建com.itcast.hdfsdemo包,并在該包下創(chuàng)建HDFS_CRUD.java文件,編寫Java測試類,構建Configuration和FileSystem對象,初始化一個客戶端實例進行相應的操作,具體代碼如文件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 {
      // 構造一個配置參數(shù)對象,設置一個參數(shù):我們要訪問的hdfs的URI
      Configuration conf = new Configuration();
      // 這里指定使用的是HDFS文件系統(tǒng)
      **conf.set("fs.defaultFS", "hdfs://hadoop01:9000")**;
      // 通過如下的方式進行客戶端身份的設置
      **System.setProperty("HADOOP_USER_NAME", "root")**;
      // 通過FileSystem的靜態(tài)方法獲取文件系統(tǒng)客戶端對象
      fs = FileSystem.get(conf);
    }
  }

在上述代碼中,@Before是一個用于在Junit單元測試框架中控制程序最先執(zhí)行的注解,這里可以保證init()方法在程序中最先執(zhí)行。

小提示:

FileSystem.get()方法從conf中的設置的參數(shù) fs.defaultFS的配置值,用來設置文件系統(tǒng)類型。如果代碼中沒有指定為fs.defaultFS,并且工程classpath下也沒有給定相應的配置,則conf中的默認值就來自于hadoop-common-2.7.4.jar包中的core-default.xml,默認值為:“file:/// ”,這樣獲取的不是DistributedFileSystem實例,而是一個本地文件系統(tǒng)的客戶端對象。

3.上傳文件到HDFS

初始化客戶端對象后,接下來實現(xiàn)上傳文件到HDFS的功能。由于采用Java測試類來實現(xiàn)JavaApi對HDFS的操作,因此可以在HDFS_CRUD.java文件中添加一個testAddFileToHdfs()方法來演示本地文件上傳到HDFS的示例,具體代碼如下:

@Test
public void testAddFileToHdfs() throws IOException {
  // 要上傳的文件所在本地路徑
  Path src = new Path("D:/test.txt");
  // 要上傳到hdfs的目標路徑
  Path dst = new Path("/testFile");
  // 上傳文件方法
  fs.copyFromLocalFile(src, dst);
  // 關閉資源
  fs.close();
}

從上述代碼可以看出,可以通過FileSystem對象的copyFromLocalFile()方法,將本地數(shù)據(jù)上傳至HDFS中。copyFromLocalFile()方法接收兩個參數(shù),第一個參數(shù)是要上傳的文件所在的本地路徑(需要提前創(chuàng)建),第二個參數(shù)是要上傳到HDFS的目標路徑。

4.從HDFS下載文件到本地

在HDFS_CRUD.java文件中添加一個testDownloadFileToLocal()方法,來實現(xiàn)從HDFS中下載文件到本地系統(tǒng)的功能,具體代碼如下:

// 從hdfs中復制文件到本地文件系統(tǒng)

@Test
public void testDownloadFileToLocal() throws IllegalArgumentException,
  IOException {
  // 下載文件
  fs.copyToLocalFile(new Path("/testFile"), new Path("D:/"));
    fs.close();
}

從上述代碼可以看出,可以通過FileSystem對象的copyToLocalFile()方法從HDFS上下載文件到本地。copyToLocalFile()方法接收兩個參數(shù),第一個參數(shù)是HDFS上的文件路徑,第二個參數(shù)是下載到本地的目標路徑。
注意:
在Windows平臺開發(fā)HDFS項目時,若不設置Hadoop開發(fā)環(huán)境,則會報以下的錯誤:

java.io.IOException: (null) entry in command string: null chmod 0644 D:\testFile

解決方式:

(1)根據(jù)教材提示,安裝配置windows平臺hadoop(注意,配置后必須重啟電腦),運行沒有問題。

(2)直接使用下載的hadoop linux平臺下的壓縮包進行解壓,然后在解壓包bin目錄下額外添加windows相關依賴文件(winutils.exe、winutils.pdb、hadoop.dll),然后進行hadoop環(huán)境變量配置(注意,配置后必須重啟電腦),運行同樣沒有問題。

(3)使用FileSystem自帶的方法即使不配置windows平臺hadoop也可以正常運行(這種方法下載后就是沒有附帶一個類似.testFile.crc的校驗文件):

fs.copyToLocalFile(false,new Path("/testFile"), new Path("D:/"),true);

5.目錄操作

在HDFS_CRUD.java文件中添加一個testMkdirAndDeleteAndRename()方法,實現(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);
}

從上述代碼可以看出,可以通過調(diào)用FileSystem的mkdirs()方法創(chuàng)建新的目錄;調(diào)用delete()方法可以刪除文件夾,delete()方法接收兩個參數(shù),第一個參數(shù)表示要刪除的文件夾路徑,第二個參數(shù)用于設置是否遞歸刪除目錄,其值為true或false,true表示遞歸刪除,false表示非遞歸刪除;調(diào)用rename()方法可以對文件或文件夾重命名,rename()接收兩個參數(shù),第一個參數(shù)代表需要修改的目標路徑,第二個參數(shù)代表新的命名。

6.查看目錄中的文件信息

在HDFS_CRUD.java文件中添加一個testListFiles()方法,實現(xiàn)查看目錄中所有文件的詳細信息的功能,代碼如下:

// 查看目錄信息,只顯示文件

@Test

public void testListFiles() throws FileNotFoundException,

  IllegalArgumentException, IOException {

  // 獲取迭代器對象

  RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(

                         new Path("/"), true);

  while (listFiles.hasNext()) {

    LocatedFileStatus fileStatus = listFiles.next();

    // 打印當前文件名

    System.out.println(fileStatus.getPath().getName());

    // 打印當前文件塊大小

    System.out.println(fileStatus.getBlockSize());

    // 打印當前文件權限

    System.out.println(fileStatus.getPermission());

    // 打印當前文件內(nèi)容長度

    System.out.println(fileStatus.getLen());

    // 獲取該文件塊信息(包含長度,數(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()方法獲取文件列表,其中第一個參數(shù)表示需要獲取的目錄路徑,第二個參數(shù)表示是否遞歸查詢,這里傳入?yún)?shù)為true,表示需要遞歸查詢。










猜你喜歡:

HDFS分布式文件系統(tǒng)的優(yōu)點缺點分別是什么?

HDFS的高可用架構是怎樣工作的?

HDFS存儲架構中主從節(jié)點關系?工作原理是什么?

傳智教育Python大數(shù)據(jù)開發(fā)高級軟件工程師培訓

0 分享到:
和我們在線交談!