Hadoop基礎-HDFS的API實現增刪改查


                   Hadoop基礎-HDFS的API實現增刪改查

                                      作者:尹正傑

版權聲明:原創作品,謝絕轉載!否則將追究法律責任。

 

 

  本篇博客開發IDE使用的是Idea,如果沒有安裝Idea軟件的可以去下載安裝,如何安裝IDE可以參考我的筆記:https://www.cnblogs.com/yinzhengjie/p/9080387.html。當然如果有小伙伴已經有自己使用習慣的IDE就不用更換了,只是配置好相應的Maven即可,我這里配置Maven是針對idea界面進行說明的。

 

 

一.將模塊添加maven框架支持

1>.點擊"Add Frameworks Support"

 

2>.添加Maven框架的支持

 

3>.在pom.xml中添加以下依賴關系

 

4>.啟用自動導入

 

5>.等待下載完成

 

6>.手動刷新Maven項目

 

 

 

二.將Linux服務器端的HDFS文件到項目中的resources目錄

1>.查看服務端配置文件

 [yinzhengjie@s101 ~]$ more /soft/hadoop/etc/hadoop/core-site.xml 
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://s101:8020</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/home/yinzhengjie/hadoop</value>
</property>
</configuration>

<!--

core-site.xml配置文件的作用:
用於定義系統級別的參數,如HDFS URL、Hadoop的臨時
目錄以及用於rack-aware集群中的配置文件的配置等,此中的參
數定義會覆蓋core-default.xml文件中的默認配置。

fs.defaultFS 參數的作用:
#聲明namenode的地址,相當於聲明hdfs文件系統。

hadoop.tmp.dir 參數的作用:
#聲明hadoop工作目錄的地址。

-->
[yinzhengjie@s101 ~]$ sz /soft/hadoop/etc/hadoop/core-site.xml 
rz
zmodem trl+C ȡ

100% 850 bytes 85 bytes/s 00:00:10 0 Errors

[yinzhengjie@s101 ~]$ 

2>.將下載的文件拷貝到項目中resources目錄下

 

3>.查看下載的core-site.xml 文件內容

 

三.HDFS的API實現增刪改查

  1 /*
  2 @author :yinzhengjie
  3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
  4 EMAIL:y1053419035@qq.com
  5 */
  6 package cn.org.yinzhengjie.day01.note1;
  7 
  8 import org.apache.hadoop.conf.Configuration;
  9 import org.apache.hadoop.fs.FSDataInputStream;
 10 import org.apache.hadoop.fs.FSDataOutputStream;
 11 import org.apache.hadoop.fs.FileSystem;
 12 import org.apache.hadoop.fs.Path;
 13 import java.io.IOException;
 14 
 15 public class HdfsDemo {
 16     public static void main(String[] args) throws IOException {
 17         insert();
 18         update();
 19         read();
 20         delete();
 21     }
 22 
 23     //刪除文件
 24     private static void delete() throws IOException {
 25         //由於我的Hadoop完全分布式根目錄對yinzhengjie以外的用戶(盡管是root用戶也沒有寫入權限喲!因為是hdfs系統,並非Linux系統!)沒有寫入
 26         // 權限,所以需要手動指定當前用戶權限。使用“HADOOP_USER_NAME”屬性就可以輕松搞定!
 27         System.setProperty("HADOOP_USER_NAME","yinzhengjie");
 28         //實例化一個Configuration,它會自動去加載本地的core-site.xml配置文件的fs.defaultFS屬性。(該文件放在項目的resources目錄即可。)
 29         Configuration conf = new Configuration();
 30         //代碼的入口點,初始化HDFS文件系統,此時我們需要把讀取到的fs.defaultFS屬性傳給fs對象。
 31         FileSystem fs = FileSystem.get(conf);
 32         //這個path是指是需要在文件系統中寫入的數據,里面的字符串可以寫出“hdfs://s101:8020/yinzhengjie.sql”,但由於core-site.xml配置
 33         // 文件中已經有“hdfs://s101:8020”字樣的前綴,因此我們這里可以直接寫文件名稱
 34         Path path = new Path("/yinzhengjie.sql");
 35         //通過fs的delete方法可以刪除文件,第一個參數指的是刪除文件對象,第二參數是指遞歸刪除,一般用作刪除目錄
 36         boolean res = fs.delete(path, true);
 37         if (res == true){
 38             System.out.println("====================");
 39             System.out.println(path + "文件刪除成功!");
 40             System.out.println("====================");
 41         }
 42         //釋放資源
 43         fs.close();
 44     }
 45 
 46     //將數據追加到文件內容中
 47     private static void update() throws IOException {
 48         //由於我的Hadoop完全分布式根目錄對yinzhengjie以外的用戶(盡管是root用戶也沒有寫入權限喲!因為是hdfs系統,並非Linux系統!)沒有寫入
 49         // 權限,所以需要手動指定當前用戶權限。使用“HADOOP_USER_NAME”屬性就可以輕松搞定!
 50         System.setProperty("HADOOP_USER_NAME","yinzhengjie");
 51 
 52         //實例化一個Configuration,它會自動去加載本地的core-site.xml配置文件的fs.defaultFS屬性。(該文件放在項目的resources目錄即可。)
 53         Configuration conf = new Configuration();
 54         //代碼的入口點,初始化HDFS文件系統,此時我們需要把讀取到的fs.defaultFS屬性傳給fs對象。
 55         FileSystem fs = FileSystem.get(conf);
 56         //這個path是指是需要在文件系統中寫入的數據,里面的字符串可以寫出“hdfs://s101:8020/yinzhengjie.sql”,但由於core-site.xml配置
 57         // 文件中已經有“hdfs://s101:8020”字樣的前綴,因此我們這里可以直接寫文件名稱
 58         Path path = new Path("/yinzhengjie.sql");
 59         //通過fs的append方法實現對文件的追加操作
 60         FSDataOutputStream fos = fs.append(path);
 61         //通過fos寫入數據
 62         fos.write("\nyinzhengjie".getBytes());
 63         //釋放資源
 64         fos.close();
 65         fs.close();
 66 
 67     }
 68 
 69     //將數據寫入HDFS文件系統
 70     private static void insert() throws IOException {
 71        //由於我的Hadoop完全分布式根目錄對yinzhengjie以外的用戶(盡管是root用戶也沒有寫入權限喲!因為是hdfs系統,並非Linux系統!)沒有寫入
 72         // 權限,所以需要手動指定當前用戶權限。使用“HADOOP_USER_NAME”屬性就可以輕松搞定!
 73         System.setProperty("HADOOP_USER_NAME","yinzhengjie");
 74 
 75         //實例化一個Configuration,它會自動去加載本地的core-site.xml配置文件的fs.defaultFS屬性。(該文件放在項目的resources目錄即可。)
 76         Configuration conf = new Configuration();
 77         //代碼的入口點,初始化HDFS文件系統,此時我們需要把讀取到的fs.defaultFS屬性傳給fs對象。
 78         FileSystem fs = FileSystem.get(conf);
 79         //這個path是指是需要在文件系統中寫入的數據,里面的字符串可以寫出“hdfs://s101:8020/yinzhengjie.sql”,但由於core-site.xml配置
 80         // 文件中已經有“hdfs://s101:8020”字樣的前綴,因此我們這里可以直接寫文件名稱
 81         Path path = new Path("/yinzhengjie.sql");
 82         //通過fs的create方法創建一個文件輸出對象,第一個參數是hdfs的系統路徑,第二個參數是判斷第一個參數(也就是文件系統的路徑)是否存在,如果存在就覆蓋!
 83         FSDataOutputStream fos = fs.create(path,true);
 84         //通過fos寫入數據
 85         fos.writeUTF("尹正傑");
 86         //釋放資源
 87         fos.close();
 88         fs.close();
 89     }
 90 
 91     //在HDFS文件系統中讀取數據
 92     private static void read() throws IOException {
 93         //實例化一個Configuration,它會自動去加載本地的core-site.xml配置文件的fs.defaultFS屬性。(該文件放在項目的resources目錄即可。)
 94         Configuration conf = new Configuration();
 95         //代碼的入口點,初始化HDFS文件系統,此時我們需要把讀取到的fs.defaultFS屬性傳給fs對象。
 96         FileSystem fs = FileSystem.get(conf);
 97         //這個path是指NameNode中的HDFS分布式系統中的路徑映射(注意,我這里寫的是主機名,你可以寫IP,如果是測試環境的話需要在hosts文件中添加主機名映射喲!)
 98         Path path = new Path("hdfs://s101:8020/yinzhengjie.sql");
 99         //通過fs讀取數據
100         FSDataInputStream fis = fs.open(path);
101         int len = 0;
102         byte[] buf = new byte[4096];
103         while ((len = fis.read(buf)) != -1){
104             System.out.println(new String(buf, 0, len));
105         }
106     }
107 }
108 
109 
110 /*
111 以上代碼執行結果如下:
112      尹正傑
113 yinzhengjie
114 ====================
115 /yinzhengjie.sql文件刪除成功!
116 ====================
117  */

 

四.HDFS的API實現文件拷貝(不需要我們自己實現數據流的拷貝,而是使用Hadoop自帶的IOUtils類實現)

 1 /*
 2 @author :yinzhengjie
 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 4 EMAIL:y1053419035@qq.com
 5 */
 6 package cn.org.yinzhengjie.day01.note1;
 7 
 8 import org.apache.hadoop.conf.Configuration;
 9 import org.apache.hadoop.fs.FSDataInputStream;
10 import org.apache.hadoop.fs.FileSystem;
11 import org.apache.hadoop.fs.Path;
12 import org.apache.hadoop.io.IOUtils;
13 
14 import java.io.FileOutputStream;
15 import java.io.IOException;
16 
17 public class HdfsDemo1 {
18     public static void main(String[] args) throws IOException {
19         get();
20     }
21 
22     //定義方法下載文件到本地
23     private static void get() throws IOException {
24         //由於我的Hadoop完全分布式根目錄對yinzhengjie以外的用戶(盡管是root用戶也沒有寫入權限喲!因為是hdfs系統,並非Linux系統!)沒有寫入
25         // 權限,所以需要手動指定當前用戶權限。使用“HADOOP_USER_NAME”屬性就可以輕松搞定!
26         System.setProperty("HADOOP_USER_NAME","yinzhengjie");
27         //實例化一個Configuration,它會自動去加載本地的core-site.xml配置文件的fs.defaultFS屬性。(該文件放在項目的resources目錄即可。)
28         Configuration conf = new Configuration();
29         //代碼的入口點,初始化HDFS文件系統,此時我們需要把讀取到的fs.defaultFS屬性傳給fs對象。
30         FileSystem fs = FileSystem.get(conf);
31         //這個path是指是需要在文件系統中寫入的數據,里面的字符串可以寫出“hdfs://s101:8020/xrsync.sh”,但由於core-site.xml配置
32         // 文件中已經有“hdfs://s101:8020”字樣的前綴,因此我們這里可以直接寫相對路徑
33         Path path = new Path("/xrsync.sh");
34         //通過fs的open方法獲取一個對象輸入流
35         FSDataInputStream fis = fs.open(path);
36         //創建一個對象輸出流
37         FileOutputStream fos = new FileOutputStream("yinzhengjie.sql");
38         //通過Hadoop提供的IOUtiles工具類的copyBytes方法拷貝數據,第一個參數是需要傳一個輸入流,第二個參數需要傳入一個輸出流,第三個指定傳輸數據的緩沖區大小。
39         IOUtils.copyBytes(fis,fos,4096);
40         System.out.println("文件拷貝成功!");
41         //別忘了釋放資源喲
42         fis.close();
43         fos.close();
44         fs.close();
45     }
46 }
47 
48 /*
49 以上代碼執行結果如下:
50 文件拷貝成功!
51  */

 

五.自定義塊大小寫入文件

  配置Hadoop的最小blocksize,必須是512的倍數,有可能你會問為什么要設置大小是512的倍數呢?因為hdfs在寫入的過程中會進行校驗,每512字節進行依次校驗,因此需要設置是512的倍數。編輯“hdfs-site.xml”配置文件。

1>.服務器端hdfs的配置文件,修改默認的塊大小,默認塊大小是1048576字節,我們手動改為1024字節,配合過程如下:(別忘記重啟服務,修改配置文件一般都是需要重啟服務的喲)

[yinzhengjie@s101 ~]$ more `which xrsync.sh`
#!/bin/bash
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie
#EMAIL:y1053419035@qq.com

#判斷用戶是否傳參
if [ $# -lt 1 ];then
        echo "請輸入參數";
        exit
fi


#獲取文件路徑
file=$@

#獲取子路徑
filename=`basename $file`

#獲取父路徑
dirpath=`dirname $file`

#獲取完整路徑
cd $dirpath
fullpath=`pwd -P`

#同步文件到DataNode
for (( i=102;i<=104;i++ ))
do
        #使終端變綠色 
        tput setaf 2
        echo =========== s$i %file ===========
        #使終端變回原來的顏色,即白灰色
        tput setaf 7
        #遠程執行命令
        rsync -lr $filename `whoami`@s$i:$fullpath
        #判斷命令是否執行成功
        if [ $? == 0 ];then
                echo "命令執行成功"
        fi
done
[yinzhengjie@s101 ~]$ 
[yinzhengjie@s101 ~]$ more /soft/hadoop/etc/hadoop/hdfs-site.xml 
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
        <property>
                <name>dfs.replication</name>
                <value>3</value>
        </property>
        <property>
                <name>dfs.namenode.fs-limits.min-block-size</name>
                <value>1024</value>
        </property>
</configuration>

<!--
hdfs-site.xml 配置文件的作用:
        #HDFS的相關設定,如文件副本的個數、塊大小及是否使用強制權限
等,此中的參數定義會覆蓋hdfs-default.xml文件中的默認配置.

dfs.replication 參數的作用:
        #為了數據可用性及冗余的目的,HDFS會在多個節點上保存同一個數據
塊的多個副本,其默認為3個。而只有一個節點的偽分布式環境中其僅用
保存一個副本即可,這可以通過dfs.replication屬性進行定義。它是一個
軟件級備份。

dfs.namenode.fs-limits.min-block-size 參數的作用:
  #該參數是用指定hdfs最小塊存儲設置
--> [yinzhengjie@s101 ~]$ xrsync.sh /soft/hadoop/etc/full/hdfs-site.xml =========== s102 %file =========== 命令執行成功 =========== s103 %file =========== 命令執行成功 =========== s104 %file =========== 命令執行成功 [yinzhengjie@s101 ~]$

2>.客戶端編寫API代碼如下

/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.day01.note1;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;
import java.io.FileInputStream;
import java.io.IOException;

public class HdfsDemo4 {
    public static void main(String[] args) throws IOException {
        String path = "F:/yinzhengjie.sql";
        customWrite(path);
    }

    //定制化寫入副本數和塊大小(blocksize)
    private static void customWrite(String path) throws IOException {
        //由於我的Hadoop完全分布式根目錄對yinzhengjie以外的用戶(盡管是root用戶也沒有寫入權限喲!因為是hdfs系統,並非Linux系統!)沒有寫入
        // 權限,所以需要手動指定當前用戶權限。使用“HADOOP_USER_NAME”屬性就可以輕松搞定!
        System.setProperty("HADOOP_USER_NAME","yinzhengjie");
        //實例化一個Configuration,它會自動去加載本地的core-site.xml配置文件的fs.defaultFS屬性。(該文件放在項目的resources目錄即可。)
        Configuration conf = new Configuration();
        //代碼的入口點,初始化HDFS文件系統,此時我們需要把讀取到的fs.defaultFS屬性傳給fs對象。
        FileSystem fs = FileSystem.get(conf);
        //這個path是指是需要在文件系統中寫入的數據,里面的字符串可以寫出“hdfs://s101:8020/yinzhengjie.sql”,但由於core-site.xml配置文件中已經有“hdfs://s101:8020”字樣的前綴,因此我們這里可以直接寫相對路徑
        Path hdfsPath = new Path("/yinzhengjie.sql");
        //通過fs的create方法創建一個文件輸出對象,第一個參數是hdfs的系統路徑,第二個參數是判斷第一個參數(也就是文件系統的路徑)是否存在,如果存在就覆蓋!第三個參數是指定緩沖區大小,第四個參數是指定存儲的副本數(規定數據類型必須為short類型),第五個參數是指定塊大小。
        FSDataOutputStream fos = fs.create(hdfsPath,true,1024,(short) 8,2048);
        //創建出本地的文件輸入流,也就是我們真正想要上傳的文件。
        FileInputStream fis = new FileInputStream(path);
        //拷貝文件
       IOUtils.copyBytes(fis,fos,1024);
       //釋放資源
        fos.close();
        fis.close();
    }
}

3>.客戶端通過瀏覽器訪問NameNode的WEBUI

 

   看完上面的信息發現和API設置的幾乎一致呢,那必定得一致啊,由於塊大小是2KB,而上傳的文件是19.25kb,最少得10個塊進行存儲,我們也可以通過WEBUI來查看。

 


免責聲明!

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



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