1. 程式人生 > >hdfs客戶端的理解,多種方式操作hdfs

hdfs客戶端的理解,多種方式操作hdfs

hdfs的客戶端有多種形式:
1、網頁形式
2、命令列形式
3、客戶端在哪裡執行,沒有約束,只要執行客戶端的機器能夠跟hdfs叢集通訊即可
檔案的切塊大小和儲存的副本數量,都是由客戶端決定!
所謂的由客戶端決定,是通過配置引數來定的
hdfs的客戶端會讀以下兩個引數,來決定切塊大小、副本數量:
切塊大小的引數: dfs.blocksize
副本數量的引數: dfs.replication
這兩個配置檔案只對客戶端起作用,上傳檔案的時候,副本數量和檔案的塊大小,就是由則這兩個引數決定的。

命令列操作hdfs

準備任意一臺機器,上面放一個hadoop安裝目錄
然後,配置hadoop-env.sh,新增JAVA_HOME
然後,配置core-site.xml,寫一個引數fs.defaultFS:值為hdfs叢集的uri
(hdfs://hdp-01:9000)
然後,用安裝目錄中的hadoop命令即可啟動hdfs的命令列客戶端

hdfs命令列客戶端的所有命令列表
Usage: hadoop fs [generic options]
[-appendToFile … ] 同時上傳多個檔案到HDFS
[-cat [-ignoreCrc] …] 檢視檔案內容
[-checksum …] //校驗完整性?不清楚這個
[-chgrp [-R] GROUP PATH…] 修改檔案所屬組
[-chmod [-R] 《MODE[,MODE]… | OCTALMODE> PATH…] 修改檔案許可權
[-chown [-R] [OWNER][:[GROUP]] PATH…] 修改檔案所有者及組
[-copyFromLocal [-f] [-p] [-l] [-d] … ] 本地copy檔案到hdfs=上傳
[-copyToLocal [-f] [-p] [-ignoreCrc] [-crc] … ] 從hdfs copy檔案到本地=下載
[-count [-q] [-h] [-v] [-t []] [-u] [-x] …] 統計檔案及資料夾數目
[-cp [-f] [-p | -p[topax]] [-d] … ] 拷貝
[-createSnapshot []] 建立快照(資料備份)
[-deleteSnapshot ] 刪除快照
[-df [-h] [ …]] 磁碟空間大小
[-du [-s] [-h] [-x] …] 資料夾/檔案總大小
[-expunge] 清空回收站(檔案被刪除時會移到臨時目錄.Trash/中,當超過延遲時間之後,檔案才會被永久刪除)
[-find … …] 查詢
[-get [-f] [-p] [-ignoreCrc] [-crc] … ] 下載
[-getfacl [-R] ] 檢視ACL(訪問許可權組擁有者)
[-getfattr [-R] {-n name | -d} [-e en] ] 顯示副檔名
[-getmerge [-nl] [-skip-empty-file] ] 合併多個檔案下載
[-help [cmd …]] 幫助。。。
[-ls [-C] [-d] [-h] [-q] [-R] [-t] [-S] [-r] [-u] [ …]] 檢視目錄。。。
[-mkdir [-p] …] 建立資料夾
[-moveFromLocal … ] 本地移動檔案到hdfs
[-moveToLocal ] 從hdfs移動檔案到本地
[-mv … ] hdfs內移動
[-put [-f] [-p] [-l] [-d] … ] 上傳
[-renameSnapshot ] 重新命名快照
[-rm [-f] [-r|-R] [-skipTrash] [-safely] …] 刪除檔案/資料夾
[-rmdir [–ignore-fail-on-non-empty]

…] 遞迴刪除
[-setfacl [-R] [{-b|-k} {-m|-x } ]|[–set ]] 設定ACL
[-setfattr {-n name [-v value] | -x name} ] 設定副檔名
[-setrep [-R] [-w] …] 設定副本數
[-stat [format] …] 顯示檔案統計資訊
[-tail [-f] ] 檢視檔案尾部資訊
[-test -[defsz] ] 檢視檔案資訊(-e PATH是否存在,-z 檔案是否為空,-d 是否為目錄)
[-text [-ignoreCrc] …] 產看檔案內容
[-touchz …] 建立空檔案
[-truncate [-w] …] 檔案尾部截斷
[-usage [cmd …]] 顯示給定命令或所有命令用法,對比help不含說明文件

其中常用的
1、檢視hdfs中的目錄資訊
hadoop fs -ls /hdfs路徑
hadoop fs -ls /bbb/xxx/
hadoop fs -ls -R / ##遞迴顯示指定路徑下的所有檔案和資料夾資訊

2、上傳檔案到hdfs中
hadoop fs -put test.txt /
hadoop fs -copyFromLocal test.txt /test.txt.2
copyFromLocal等價於 put
hadoop fs -moveFromLocal /本地檔案 /hdfs路徑 ## 跟copyFromLocal的區別是:從本地移動到hdfs中

3、下載檔案到客戶端本地磁碟
hadoop fs -get /hdfs中的路徑 /本地磁碟目錄
hadoop fs -copyToLocal /hdfs中的路徑 /本地磁碟路徑 ## 跟get等價
hadoop fs -get /test.txt.2
hadoop fs -copyToLocal /test.txt.2

4、在hdfs中建立資料夾
hadoop fs -mkdir /aaa
hadoop fs -mkdir -p /bbb/xxx

5、拷貝檔案
hadoop fs -cp /test.txt /bbb/

6、移動hdfs中的檔案(更名)
hadoop fs -mv /test.txt.2 /test.txt.3
hadoop fs -mv /test.txt.3 /bbb/test.txt.4

7、刪除hdfs中的檔案或資料夾
hadoop fs -rm -r /aaa

8、追加內容到已存在的檔案
hadoop fs -appendToFile /本地檔案 /hdfs中的檔案

9、顯示文字檔案的內容
hadoop fs -cat /test.txt
hadoop fs -tail /test.txt

10、下載多個檔案在本地生成一個合併檔案
hadoop fs -getmerge /test/*.dat ./xx.dat

11、修改檔案的許可權
hadoop fs -chown user:group /aaa
hadoop fs -chmod 700 /aaa

使用java api操作hdfs檔案

這裡採用的windows運程連線叢集

jar:hadoop安裝包中找到common和hdfs下的lib內的jar

public class hdfs {
    FileSystem fs;
@Before
public void start() throws IOException, InterruptedException, URISyntaxException {//建立連線,為了獲取root許可權,有三種方式
    //1,假裝自己是root使用者,在vm引數裡添上-DHADOOP_USER_NAME=root
    //2,假裝自己是root使用者,在系統變數設定使用者名稱為root
    /*
        Configuration conf = new Configuration();
        //需要指定hdfs檔案系統,同時指定namenode所在的機器
        conf.set("fs.defaultFS", "hdfs://hdp-01:9000"); fs.defaultFS
        //指定使用者名稱,注意是System
        System.setProperty("HADOOP_USER_NAME", "root");
        fs= FileSystem.get(conf);
    */
    //直接在連線時指定使用者名稱
    Configuration conf = new Configuration();
    conf.set("dfs.replication", "2");
    conf.set("dfs.blocksize","64m");
     fs= FileSystem.get(new URI("hdfs://hdp-01:9000"),conf,"root");

}
//上傳
@Test
public void put() throws IOException {//覆蓋上傳
    Path src = new Path("G:/result2.txt");
    Path dst = new Path("/test");   
    fs.copyFromLocalFile(src, dst);
}
//下載
@Test
public void load() throws IOException {//覆蓋上傳
    Path src = new Path("G:/result2.txt");
    Path dst = new Path("/test/result.txt");    
    fs.copyToLocalFile(dst, src);
}
//新建資料夾
@Test
public void add() throws Exception {
    fs.mkdirs(new Path("/path"));
}
//刪除檔案或資料夾,bollean代表是否遞迴刪除
@Test
public void delete() throws IOException {
    fs.delete(new Path("/result.txt"),true);

}
//修改檔案
@Test
public void update() throws Exception {
    FSDataOutputStream append = fs.append(new Path("/result2.txt"));//追加 >>
    //FSDataOutputStream append = fs.create(new Path("/result2.txt"));//覆蓋 > 其實是建立新檔案 echo "" > xxx
    //FSDataOutputStream append = fs.create(new Path("/result2.txt"),false);//設定為不覆蓋,如果檔案已存在,將執行失敗
    append.write("王八蛋黃鶴".getBytes("utf-8"));
    append.close();
    fs.close();

}
//讀檔案
@Test
public void show()throws Exception {
    FSDataInputStream inputStream = fs.open(new Path("/result2.txt"));
    byte[] b = new byte[1024] ;
    int len=0;
    while((len=inputStream.read(b))>0) {

    String str = new String(b);
    System.out.println(str);
    }
    inputStream.close();
    fs.close();
}
//移動和重新命名
@Test
public void move() throws Exception {
    fs.rename(new Path("/test/result.txt"), new Path("/result2.txt"));
}
//判斷是否存在
@Test
public void testExist() throws Exception{
    boolean exists = fs.exists(new Path("/result2.txt"));
    System.out.println(exists);
}
// 隨機讀檔案
@Test
public void randomRead() throws Exception{
    FSDataInputStream open = fs.open(new Path("/result2.txt"));
    open.seek(2);
    byte [] buff = new byte [10];
    open.read(buff);    
    System.out.println(new String(buff));
}

// 檢視檔案的相關資訊
@Test
public void testLisFile() throws Exception{
    RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);//true表示遞迴
    while (listFiles.hasNext()) {
        LocatedFileStatus file = listFiles.next();//檔案資訊
        System.out.println("最後訪問時間:"+new Date(file.getAccessTime()));//不算本次
        System.out.println("塊大小:"+file.getBlockSize());
        System.out.println("檔案路徑:"+file.getPath());
        System.out.println("副本數量:"+file.getReplication());
        System.out.println("檔案所有者"+file.getOwner()+"所屬的組"+file.getGroup());
        BlockLocation[] blockLocation = file.getBlockLocations();
        System.out.println("---檔案塊資訊----");
        for (BlockLocation blk: blockLocation ) {
            System.out.println("---塊大小="+blk.getLength());
            System.out.println("塊所在的節點:"+Arrays.toString(blk.getHosts()));
            System.out.println("塊的起始偏移量:"+blk.getOffset());

        }
        System.out.println("----------------------");
    }
}
//檢視資料夾的相關資訊
@Test
public void testListStatus() throws Exception{
    FileStatus[] listStatus = fs.listStatus(new Path("/"));
    for (FileStatus fss : listStatus) {
        System.out.println("路徑:"+fss.getPath());
        System.out.println(fss.isFile()?"是檔案":"是目錄");
        System.out.println("塊大小引數:"+fss.getBlockSize());
    }
}
//複製
@Test
public void copy() {//貌似不支援,似乎也不需要

}
}