Hadoop日記Day9---HDFS的java訪問接口


一、搭建Hadoop 開發環境

  我們在工作中寫完的各種代碼是在服務器中運行的,HDFS 的操作代碼也不例外。在開發階段,我們使用windows 下的eclipse 作為開發環境,訪問運行在虛擬機中的HDFS。也就是通過在本地的eclipse 中的java 代碼訪問遠程linux 中的hdfs。
要使用宿主機中的java 代碼訪問客戶機中的hdfs,需要保證以下幾點:
(1)確保宿主機與客戶機的網絡是互通的
(2)確保宿主機和客戶機的防火牆都關閉,因為很多端口需要通過,為了減少防火牆配置,直接關閉.
(3)確保宿主機與客戶機使用的jdk 版本一致。如果客戶機為jdk6,宿主機為jdk7,那么代碼運行時會報不支持的版本的錯誤。
(4)宿主機的登錄用戶名必須與客戶機的用戶名一直。比如我們linux 使用的是root 用戶,那么windows 也要使用root 用戶,否則會報權限異常
 在eclipse 項目中覆蓋hadoop 的org.apache.hadoop.fs.FileUtil 類checkReturnValue 方法,如圖1.1,目的是為了避免權限錯誤

圖1.1

  如果讀者在開發過程中出現權限等問題,請按照本節的提示檢查自己的環境。

二、使用FileSystem api 讀寫數據

  在hadoop 的HDFS 操作中,有個非常重要的api,是org.apache.hadoop.fs.FileSystem,這是我們用戶代碼操作HDFS 的直接入口,該類含有操作HDFS 的各種方法,類似於jdbc 中操作數據庫的直接入口是Connection 類

那我們怎么獲得一個FileSystem 對象

1   String uri = "hdfs://10.1.14.24:9000/";
2             Configuration conf = new Configuration();
3             FileSystem fs = FileSystem.get(URI.create(uri), conf);
View Code

以上代碼中,要注意調用的是FileSystem 的靜態方法get,傳遞兩個值給形式參數,第一個訪問的HDFS 地址,該地址的協議是hdfs,ip 是10.1.14.24,端口是9000。這個地址的完整信息是在配置文件core-site.xml 中指定的,讀者可以使用自己環境的配置文件中的設置。第二個參數是一個配置對象

1. 創建文件夾

使用HDFS 的shell 命令查看一下根目錄下的文件情況,如圖2.1所示

image

圖2.1

我們在HDFS 的根目錄下創建文件夾,代碼如下

------------------------------------------------------------------------------------------------------

            final String pathString = "/d1";
            boolean exists = fs.exists(new Path(pathString));
            if(!exists){
            boolean result = fs.mkdirs(new Path(pathString));
            System.out.println(result);
            }

------------------------------------------------------------------------------------------------------

以上代碼中要放在Main函數中

  • 第一行決定創建的文件夾完整路徑是“/d1”。
  • 第二行代碼是使用方法exitst判斷文件夾是否存在;如果不存在,執行創建操作。
  • 第三行創建文件夾,調用的是mkdirs 方法,返回值是布爾值,如果是true,表示創建成功;如果是false,表示創建失敗。

現在查看一下是否成功了,如圖3.2,3.3可見創建成功了。

image
圖3.2

image

圖 3.3

2. 寫文件

我們可以向HDFS 寫入文件,代碼如下:

-----------------------------------------------------------------------------------------------------

final String pathString = "/d1/f1";
final FSDataOutputStream fsDataOutputStream = fs.create(new Path(pathString));//寫出去
IOUtils.copyBytes(new ByteArrayInputStream("my name is Sunddenly".getBytes()),
fsDataOutputStream, conf, true);

------------------------------------------------------------------------------------------------------
第一行代碼表示創建的文件是在剛才創建的d1 文件夾下的文件f1;
第二行是調用create 方法創建一個通向HDFS 的輸出流
第三行是通過調用hadoop 的一個工具類IOUtils 的靜態方法copyBytes 把一個字符串發送給輸出流中。

該靜態方法有四個參數:

  • 第一個參數輸入流
  • 第二個參數是輸出流
  • 第三個參數是配置對象
  • 第四個參數是布爾值,如果是true 表示數據傳輸完畢后關閉流

現在看一下是否創建成功了,如圖3.4所示。

image

圖3.4

3. 讀文件

現在我們把剛才寫入到HDFS 的文件“/d1/f1”讀出來,代碼如下:

------------------------------------------------------------------------------------------------------
    final String pathString = "/d1/f1";
    final FSDataInputStream fsDataInputStream = fs.open(new Path(pathString));//讀進來
    IOUtils.copyBytes(fsDataInputStream, System.out, conf, true);

-------------------------------------------------------------------------------------------------------

  • 第一行指定所讀文件的路徑。
  • 第二行表示調用方法open 打開一個指定的文件,返回值是一個通向該文件的輸入流
  • 第三行還是調用IOUtils.copyBytes 方法,輸出的目的地是控制台。

見圖3.5

image
圖3.5

4. 查看目錄列表和文件詳細信息

我們可以把根目錄下的所有文件和目錄顯示出來,代碼如下

--------------------------------------------------------------------------------------------------------
    final String pathString = "/";
    final FileStatus[] listStatus = fs.listStatus(new Path(pathString));
    for (FileStatus fileStatus : listStatus) {
      final String type = fileStatus.isDir()?"目錄":"文件";
      final short replication = fileStatus.getReplication();
      final String permission = fileStatus.getPermission() .toString();
      final long len = fileStatus.getLen();
      final Path path = fileStatus.getPath();
      System.out.println(type+"\t"+permission+"\t"+replication+"\t"+len+"\t"+path);
    }

-----------------------------------------------------------------------------------------------------------
  調用listStatus方法會得到一個指定路徑下的所有文件和文件夾,每一個用FileStatus表示。我們使用for循環顯示每一個FileStatus對象。FileStatus對象表示文件的詳細信息,里面含有類型、副本數、權限、長度、路徑等很多信息,我們只是顯示了一部分。結果如圖3.6所示。

image
圖 3.6

5. 刪除文件或目錄

  我們可以刪除某個文件或者路徑,代碼如下

-----------------------------------------------------------------------------------------------------
    final String pathString = "/d1/f1";
    //fs.delete(new Path("/d1"), true);
    fs.deleteOnExit(new Path(pathString));

-----------------------------------------------------------------------------------------------------
  第三行代碼表示刪除文件“/d1/f1”,注釋掉的第二行代碼表示遞歸刪除目錄“/d1”及下面的所有內容。除了上面列出的fs 的方法外,還有很多方法,請讀者自己查閱api。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM