Java Api操作HDFS


小廣告...:https://www.mvclub.xyz/【個人搭建的一個電影網站】

使用idea工具

創建的是maven項目,操作linux環境

首先需要配置好Maven環境,如果下載jar包下的慢,可以將鏡像站換為阿里雲的鏡像【配置maven環境參考:...............(待完成)】

准備工作完成即可開始編寫代碼

1.創建maven項目

 

 

2.在pom.xml里面導入依賴

 pom.xml中所使用到的jar包【自行去maven倉庫找jar包,認准下載量最多的。https://mvnrepository.com/

如果網站加載的太慢,可以去阿里雲的maven倉庫找:https://maven.aliyun.com/

hadoop-common,hadoop-hdfs,hadoop-client【3個版本保持一致】

 1   <dependencies>
 2     <!--測試用-->
 3     <dependency>
 4       <groupId>junit</groupId>
 5       <artifactId>junit</artifactId>
 6       <version>4.11</version>
 7       <scope>test</scope>
 8     </dependency>
 9     <!--COMMON是hadoop一切的核心,不是具體的功能,操作HDFS需要導入COMMON的依賴-->
10     <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-common -->
11     <dependency>
12       <groupId>org.apache.hadoop</groupId>
13       <artifactId>hadoop-common</artifactId>
14       <version>2.7.3</version>
15     </dependency>
16     <!--hadoop也是基於客戶端服務器的-->
17     <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-client -->
18     <dependency>
19       <groupId>org.apache.hadoop</groupId>
20       <artifactId>hadoop-client</artifactId>
21       <version>2.7.3</version>
22     </dependency>
23     <!--操作MapReduce需要HDFS的依賴-->
24     <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs -->
25     <dependency>
26       <groupId>org.apache.hadoop</groupId>
27       <artifactId>hadoop-hdfs</artifactId>
28       <version>2.7.3</version>
29     </dependency>
30   </dependencies>

3.開始編寫代碼

3.1.連接HDFS

    //連接HDFS
    @Test //測試
    public void connectHDFS(){
        //先添加一個配置文件--和core-site.xml的配置一樣[相當於服務器的端口]
        Configuration conf = new Configuration();
        //配置服務器的地址和端口
        conf.set("fs.defaultFS","hdfs://192.168.0.10:9000");
        try {
            //加載我們的配置文件,然后連接到服務上去【前提,hadoop的環境配好,啟動起來】
            FileSystem fileSystem = FileSystem.get(conf);
            //如何判斷是否已經連上?
            //getFileStatus是獲取當前某個路徑的狀態
            FileStatus status = fileSystem.getFileStatus(new Path("/test.txt"));
            System.out.println(status.isFile()); //判斷是不是一個文件
            System.out.println(status.isDirectory()); //判斷是不是一個目錄
            System.out.println(status.getPath()); //獲取文件的路徑
            System.out.println(status.getLen()); //獲取文件的大小
            //關閉連接
            fileSystem.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

3.2.文件上傳到HDFS【linux命令:hadoop fs -put】

    //上傳文件到HDFS
    @Test //測試
    public void  upload1(){
        //添加配置文件
        Configuration conf = new Configuration();
        //如果報一個錯誤:
        //user=Machenike, access=WRITE, inode="/":root:supergroup:drwxr-xr-x
        //解決1:直接添加System.setProperty("HADOOP_USER_NAME", "root"); 設置為root用戶
        //解決2:在環境變量中添加 HADOOP_USER_NAME 值為root
        System.setProperty("HADOOP_USER_NAME", "root");
        try {
            //加載配置文件
            FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf);
            //獲取一個輸出流
            FSDataOutputStream out = fileSystem.create(new Path("/upload.txt"));
            //獲取本地文件的一個輸入流
            FileInputStream in = new FileInputStream(new File("F:\\upload.txt"));
            //先定義一個byte類型的數組,數組長度1024
            //該數組的大小表示每次從文件中讀取出來的數據量
            byte[] b = new byte[1024];
            int len = 0;
            //判斷文件是否讀完
            while((len=in.read(b))!=-1){
                //對這些數據量進行輸出
                //b-表示要寫的數據,0-表示從0開始,len-表示寫的字節數
                out.write(b,0,len);
            }
            //將輸入流和輸出流關閉
            in.close();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

    //文件上傳方式2-直接使用hadoop提供的一個工具類IOUtils
    @Test //測試
    public void  upload2(){
        //添加配置文件
        Configuration conf = new Configuration();
        try {
            //加載配置文件
            FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf);
            //獲取一個輸出流
            FSDataOutputStream out = fileSystem.create(new Path("/upload1.txt"));
            //獲取本地文件的一個輸入流
            FileInputStream in = new FileInputStream(new File("F:\\upload.txt"));
            //執行上傳操作
            IOUtils.copyBytes(in,out,conf);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

可能會遇到如下錯誤:如何解決?

解決辦法:

  1.直接在代碼中設置屬性->System.setProperty("HADOOP_USER_NAME", "root");

  2.在環境變量中添加HADOOP_USER_NAME 值為root即可【如果不行,重啟idea,再不行就重啟電腦就OK了】

 3.3.從HDFS上下載文件到本地【linux命令:hadoop fs -get】

    //文件下載
    @Test
    public void download(){
        //添加配置文件
        Configuration conf = new Configuration();
        try {
            //加載配置文件
            FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf);
            //獲取輸入流的數據
            FSDataInputStream in = fileSystem.open(new Path("/upload.txt"));
            //獲取本地文件的輸出流
            FileOutputStream out = new FileOutputStream(new File("F:\\download.txt"));

            //下載的方式同樣有兩種【下載就是拷貝】
            //方式1:工具類操作
//            IOUtils.copyBytes(in,out,conf);

            //方式2:
            byte[] b = new byte[1024];
            int len = 0;
            while((len=in.read(b))!=-1){
                out.write(b,0,len);
            }

            //關閉連接
            in.close();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

3.4.修改HDFS下的文件名

    //重命名
    @Test //測試
    public void rename(){
        //添加配置文件
        Configuration conf = new Configuration();
        try {
            //加載配置文件
            FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf);
            //重命名
            boolean rename = fileSystem.rename(new Path("/upload.txt"), new Path("/upload3.txt"));
            System.out.println(rename?"修改成功":"修改失敗");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

3.5.創建文件夾【linux命令:hadoop fs -mkdir -p】

    //創建文件夾
    @Test //測試
    public void mkdirs(){
        //添加配置文件
        Configuration conf = new Configuration();
        try {
            //加載配置文件
            FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf);
            //創建多級目錄
            boolean mkdirs = fileSystem.mkdirs(new Path("/test/test1/hello.txt"));
            System.out.println(mkdirs?"城建成功":"創建失敗");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

3.6.查看所有文件夾【linux命令:hadoop fs -lsr】

    //查看所有文件夾
    @Test //測試
    public void selectAll(){
        //添加配置文件
        Configuration conf = new Configuration();
        try {
            //加載配置文件
            FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf);
            //查詢該路徑下所有的文件信息
            FileStatus[] status = fileSystem.listStatus(new Path("/"));
            //遍歷所有的文件的狀態
            System.out.println("/");
            for (FileStatus f:status){
                //判斷是否是文件
                //f.getPath().getName() 獲取文件或文件夾的名字
                //f.getPermission() 獲取文件或文件夾的權限
                //f.getLen() 獲取文件或文件夾的大小
                if (f.isFile()){
                    System.out.println("f--"+f.getPath().getName()+"\t"+f.getPermission()+"\t"+f.getLen());
                }else{
                    System.out.println("d--"+f.getPath().getName()+"\t"+f.getPermission()+"\t"+f.getLen());
                    getNodes(f.getPath().getName(), 1);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

    //遞歸遍歷出所有的文件和文件夾【index主要就是為了打印出來的好看些,強迫症】
    public void getNodes(String dir, int index){
        //添加配置文件
        Configuration conf = new Configuration();
        try {
            //加載配置文件
            FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf);
            //得到之后新目錄的絕對路徑
            String path = "/"+dir;
            //使其具有層次感的制表符
            String tab = "\t";
            if(index > 1){
                for(int i = 1; i < index; i++){
                    tab += "\t";
                }
            }
            //獲取該路徑下的所有文件信息
            FileStatus[] status = fileSystem.listStatus(new Path(path));
            //設置讓其退出的條件【如果該路徑下沒有文件或文件夾即退出】
            if(status.length==0){
                return;
            }
            //遍歷所有的文件信息
            for (FileStatus f : status){
                if (f.isFile()){
                    System.out.println(tab+"f--"+f.getPath().getName()+"\t"+f.getPermission()+"\t"+f.getLen());
                }else{
                    System.out.println(tab+"d--"+f.getPath().getName()+"\t"+f.getPermission()+"\t"+f.getLen());
                    getNodes(dir +"/"+f.getPath().getName(), index +1);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

結果如下:


使用Eclipse工具

需要自己導入jar包。jar包如何找?【將hadoop-2.7.7.tar.gz包解壓即可】

jar包 -- 操作hdfs,需要導入Common下的jar包
    share/hadoop/common/lib下面作者引用別人的jar包
    share/hadoop/common下面自己寫的jar包
  -- 操作MapReduce,還需要導入HDFS下的jar包
    share/hadoop/hdfs/lib 下面作者引用別人的jar包
    share/hadoop/hdfs 下面作者自己寫的包

代碼部分和idea一樣的操作

 


免責聲明!

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



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