1. 程式人生 > >三、hdfs的JavaAPI操作

三、hdfs的JavaAPI操作

下文展示Java的API如何操作hdfs,在這之前你需要先安裝配置好hdfs

https://www.cnblogs.com/lay2017/p/9919905.html

依賴

你需要引入依賴如下

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-common</artifactId>
    <version>2.8.0</version>
</dependency>
<dependency
> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-hdfs</artifactId> <version>2.8.0</version> </dependency>

配置修改

core-site.xml

由於Java訪問hdfs始終都要通過nameNode來拿到dataNode節點,所以nameNode要配置為可對外訪問的地址,不能是localhost了

我們更改core-site.xml配置為虛擬機器IP即可,我們虛擬機器要作為類似伺服器的方式來使用,所以虛擬機器網路配置要是橋接模式,這樣才有獨立IP,並可對宿主機提供訪問

hdfs-site.xml

另外,對於服務端檔案的操作預設會檢查許可權,所以為了方便,你可以配置hdfs-site.xml關閉

<!-- permissions  -->
<property>
    <name>dfs.permissions</name>
    <value>false</value>
</property>

 示例程式碼

下面是Java示例程式碼,對外的API主要是由FileSystem這個抽象類來提供,它的java docs在:http://hadoop.apache.org/docs/stable/api/org/apache/hadoop/fs/FileSystem.html

 你可以檢視Java docs閱讀更多地API,這裡演示常用的上傳、下載、刪除、建立資料夾、列出檔案、列出檔案和資料夾

package cn.lay.demo.hdfs;

import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;

import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @Description hdfs java api操作示例
 * @Author lay
 * @Date 2018/11/8 0:04
 */
public class HdfsJavaApiDemo {
    // nameNode節點地址
    private static final String NAME_NODE = "hdfs://192.168.1.12:9000";
    private static Configuration configuration;
    private static FileSystem fileSystem;
    // 本地檔案
    private static final String LOCAL_FILE = "C:\\Users\\admin\\Desktop\\helloHdfs.txt";
    // 遠端檔案
    private static final String REMOTE_FILE = "/helloHdfs.txt";
    // 下載檔案
    private static final String DOWNLOAD_FILE = "C:\\Users\\admin\\Desktop\\download.txt";
    // 遠端的資料夾
    private static final String REMOTE_DIR = "/newDir/newChildDir";

    static {
        configuration = new Configuration();
        configuration.set("fs.defaultFS", NAME_NODE);
        try {
            fileSystem = FileSystem.get(configuration);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        try {
            // upload();
            // download();
            // remove();
            // mkdirs();
            // listFiles();
            listStatus();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 檔案上傳
     * @throws IOException
     */
    public static void upload() throws IOException {
        fileSystem.copyFromLocalFile(new Path(LOCAL_FILE), new Path(REMOTE_FILE));
    }

    /**
     * 檔案下載
     * @throws IOException
     */
    public static void download() throws IOException {
        // fileSystem.copyToLocalFile(new Path(REMOTE_FILE), new Path(DOWNLOAD_FILE));
        FSDataInputStream fsDataInputStream = fileSystem.open(new Path(REMOTE_FILE));
        FileOutputStream fileOutputStream = new FileOutputStream(DOWNLOAD_FILE);
        IOUtils.copy(fsDataInputStream, fileOutputStream);
        fsDataInputStream.close();
        fileOutputStream.flush();
        fileOutputStream.close();
    }

    /**
     * 刪除
     * @throws IOException
     */
    public static void remove() throws IOException {
        // 遞迴
        boolean recursive = true;
        fileSystem.delete(new Path(REMOTE_FILE), recursive);
    }

    /**
     * 建立資料夾
     * @throws IOException
     */
    public static void mkdirs() throws IOException {
        fileSystem.mkdirs(new Path(REMOTE_DIR));
    }

    /**
     * 列出檔案內容
     * @throws IOException
     */
    public static void listFiles() throws IOException {
        RemoteIterator<LocatedFileStatus> fileStatusList = fileSystem.listFiles(new Path("/"), true);
        while (fileStatusList.hasNext()) {
            LocatedFileStatus fileStatus = fileStatusList.next();
            String path = fileStatus.getPath().toString();
            System.out.println("path:" + path);
        }
    }

    /**
     * 列出資料夾和檔案
     * @throws IOException
     */
    public static void listStatus() throws IOException {
        FileStatus[] fileStatuses = fileSystem.listStatus(new Path("/"));
        for (FileStatus f : fileStatuses) {
            System.out.println("path:" + f.getPath());
        }
    }
}

注意:檔案下載採用了IO流的方式,而不是copyToLocalFile方法,因為該方法需要本地hadoop的環境配置,否則你會看到類似這樣的錯誤:

java.io.FileNotFoundException: HADOOP_HOME and hadoop.home.dir are unset

並且下載的檔案總是0byte,如果遇到這樣的問題你可以在hdfs服務端檢視目錄和檔案檢查服務端檔案有沒有問題,命令:

hadoop fs -ls /

其它API

當然hdfs也提供http的方式去訪問,可以參考:http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/WebHDFS.html

官方文件的HDFS示例講解是基於C語言的:http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/LibHdfs.html

當然你可以在hadoop的Javadocs裡面閱讀,不過不太方便因為你需要了解它的包和類:http://hadoop.apache.org/docs/current/api/