大数据学习之路(5): HDFS客户端操作

287 阅读4分钟

一、环境准备

用idea来操作hdfs的shell基本命令。因此,windows需要做些环境变量的配置。

1、下载hadoop3.1的windows依赖,此处用3.1.0来代替。配置hadoop_home

image.png

2、配置PATH环境变量

image.png

3、创建Maven工程,导入依赖。

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    
   <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-client</artifactId>
        <version>3.1.3</version>
    </dependency>
    

4、创建类:传入的是namenode的uri

public class TestHdfs {
    private URI uri=URI.create("hdfs://192.168.1.101:9820");
    private Configuration conf=new Configuration();
    private String user="lei";
    private FileSystem fs;

    @Before
    public void init() throws Exception{
        fs=FileSystem.get(uri,conf,user);
    }

    @After
    public void close() throws Exception{
        fs.close();
    }
    /**
     * 创建目录
    **/
    @Test
    public void testHdfsClient() throws IOException, InterruptedException {
        //2、操作集群
        fs.mkdirs(new Path("/java"));
    }

测试成功

image.png

二、API操作

2.1 API操作

1、参数优先级

可以在resouces写xml文件,进行配置: 注意:参数优先级排序:

(1)客户端代码中设置的值

(2)ClassPath 下的用户自定义配置文件

(3)服务器的自定义配置(xxx-site.xml)

(4)服务器的默认配置(xxx-default.xml)

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>
    <property>
        <name>dfs.replication</name>
        <value>2</value>
    </property>
</configuration>

2、文件上传

    /**
     * 文件上传
     **/
    @Test
    public void testFileUpload() throws IOException {
        fs.copyFromLocalFile(false,false,
                new Path("E:\\mycode\\mytest\\dalao.txt"),
                new Path("/java"));
    }

3、文件下载

    /**
     * 文件下载
     **/
    @Test
    public void download() throws IOException {
        fs.copyToLocalFile(false,
                new Path("/user/lei/lei.txt"),
                new Path("E:\\mycode\\mytest\\dalao2.txt"),false);
    }

4、HDFS文件夹删除

/**
 * 文件夹删除:是否递归删除true
 **/
@Test
public void testDelete() throws IOException {
    fs.delete(new Path("/java/dalao.txt"),true);
}

5、HDFS文件名更改/移动

/**
 * 文件名更改
 **/
@Test
public void testRename() throws IOException {
    fs.rename(new Path("/java/xulei.txt"),new Path("/java/leilei.txt"));
}

6、HDFS文件详情查看

查看文件名称、权限、长度、块信息。

/**
 * 获取文件详情
 **/
@Test
public void tsetFileInfo() throws IOException {
    RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);
    while (listFiles.hasNext()) {
        LocatedFileStatus status = listFiles.next();

        // 输出详情
        // 文件名称
        System.out.println(status.getPath().getName());
        // 长度
        System.out.println(status.getLen());
        // 权限
        System.out.println(status.getPermission());
        // 分组
        System.out.println(status.getGroup());

        // 获取存储的块信息
        BlockLocation[] blockLocations = status.getBlockLocations();

        for (BlockLocation blockLocation : blockLocations) {

            // 获取块存储的主机节点
            String[] hosts = blockLocation.getHosts();

            for (String host : hosts) {
                System.out.println(host);
            }
        }

        System.out.println("-----------漂亮的分割线----------");

    }
}

7、HDFS文件或文件夹判断

@Test
public void testFileStatus() throws IOException {
    FileStatus[] listStatus = fs.listStatus(new Path("/"));
    for (FileStatus fileStatus : listStatus) {

        // 如果是文件
        if (fileStatus.isFile()) {
            System.out.println("f:"+fileStatus.getPath().getName());
        }else {
            System.out.println("d:"+fileStatus.getPath().getName());
        }
    }
}

8、文件上传下载

本质就是IO流的操作,文件的操作:通过指向本地文件的输入流,进行数据的读取,然后将读取到的数据,通过指向HDFS文件的输出流,将数据写出。将D:\ziyuan\sofehere\girl.txt 上传到hdfs的java。

 @Test
    public void testupload() throws IOException {
        File srcFile=new File("D:\\ziyuan\\sofehere\\girl.txt");
        //输入流
        FileInputStream fileInputStream = new FileInputStream(srcFile);

        //输出流
        FSDataOutputStream fsDataOutputStream = fs.create(new Path("/java/hualin.txt"));

        //输入流读取,输出流写出

//        byte [] buffer=new byte[1024];
//        int i;
//        while((i=fileInputStream.read(buffer))!=-1){
//            fsDataOutputStream.write(buffer,0,i);
//        }
        //流的对拷,由hadoop提供的工具类
        IOUtils.copyBytes(fileInputStream,fsDataOutputStream,conf);
        IOUtils.closeStream(fileInputStream);
        IOUtils.closeStream(fsDataOutputStream);
    }

9、文件下载

通过指向HDFS文件的输入流,进行数据的读取,然后将读取到是数据,通过指向本地的输出流,将数据写出

@Test
public void downloadIO  () throws IOException {
    //目标文件
    File destfile=new File("D:\\ziyuan\\sofehere\\hualin.txt");
    //输入流
    FSDataInputStream open = fs.open(new Path("/java/hualin.txt"));
    //输出流
    FileOutputStream fileOutputStream = new FileOutputStream(destfile);

    //流的对拷i
    IOUtils.copyBytes(open,fileOutputStream,conf);
}

全部代码:

package com.xl.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.*;
import java.net.URI;

/**
 * @author xiao lei
 * @Date 2020/8/27
 * @module
 * 开发客户端类型的代码的套路:
 * 1、创建或者获取、客户端对象
 * 2、调用API进行具体的操作
 * 3、关闭
 */
public class TestHdfs {
    private URI uri=URI.create("hdfs://hadoop100:9820");
    private Configuration conf=new Configuration();
    private String user="leilei";
    private FileSystem fs;

    @Before
    public void init() throws Exception{
        fs=FileSystem.get(uri,conf,user);
    }

    @After
    public void close() throws Exception{
        fs.close();
    }
    /**
     * 创建目录
    **/
    @Test
    public void testHdfsClient() throws IOException, InterruptedException {
        //2、操作集群
        fs.mkdirs(new Path("/java"));
    }
    /**
     * 文件上传
     **/
    @Test
    public void testFileUpload() throws IOException {
        fs.copyFromLocalFile(false,false,
                new Path("D:\\ziyuan\\sofehere\\dalao.txt"),
                new Path("/java"));
    }
    /**
     * 文件下载
     **/
    @Test
    public void download() throws IOException {
        fs.copyToLocalFile(false,
                new Path("/java/xulei.txt"),
                new Path("D:\\ziyuan\\sofehere\\dalao.txt"),false);
    }
    /**
     * 文件夹删除
     **/
    @Test
    public void testDelete() throws IOException {
        fs.delete(new Path("/java/dalao.txt"),true);
    }
    /**
     * 文件名更改
     **/
    @Test
    public void testRename() throws IOException {
        fs.rename(new Path("/java/xulei.txt"),new Path("/java/leilei.txt"));
    }
    /**
     * 获取文件详情
     **/
    @Test
    public void tsetFileInfo() throws IOException {
        RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);
        while (listFiles.hasNext()) {
            LocatedFileStatus status = listFiles.next();

            // 输出详情
            // 文件名称
            System.out.println(status.getPath().getName());
            // 长度
            System.out.println(status.getLen());
            // 权限
            System.out.println(status.getPermission());
            // 分组
            System.out.println(status.getGroup());

            // 获取存储的块信息
            BlockLocation[] blockLocations = status.getBlockLocations();

            for (BlockLocation blockLocation : blockLocations) {

                // 获取块存储的主机节点
                String[] hosts = blockLocation.getHosts();

                for (String host : hosts) {
                    System.out.println(host);
                }
            }

            System.out.println("-----------漂亮的分割线----------");

        }
    }
    @Test
    public void testFileStatus() throws IOException {
        FileStatus[] listStatus = fs.listStatus(new Path("/"));
        for (FileStatus fileStatus : listStatus) {

            // 如果是文件
            if (fileStatus.isFile()) {
                System.out.println("f:"+fileStatus.getPath().getName());
            }else {
                System.out.println("d:"+fileStatus.getPath().getName());
            }
        }
    }

    @Test
    public void testupload() throws IOException {
        File srcFile=new File("D:\\ziyuan\\sofehere\\girl.txt");
        //输入流
        FileInputStream fileInputStream = new FileInputStream(srcFile);

        //输出流
        FSDataOutputStream fsDataOutputStream = fs.create(new Path("/java/hualin.txt"));

        //输入流读取,输出流写出

//        byte [] buffer=new byte[1024];
//        int i;
//        while((i=fileInputStream.read(buffer))!=-1){
//            fsDataOutputStream.write(buffer,0,i);
//        }
        //流的对拷,由hadoop提供的工具类
        IOUtils.copyBytes(fileInputStream,fsDataOutputStream,conf);
        //关闭流
        IOUtils.closeStream(fileInputStream);
        IOUtils.closeStream(fsDataOutputStream);
    }

    @Test
    public void downloadIO  () throws IOException {
        //目标文件
        File destfile=new File("D:\\ziyuan\\sofehere\\hualin.txt");
        //输入流
        FSDataInputStream open = fs.open(new Path("/java/hualin.txt"));
        //输出流
        FileOutputStream fileOutputStream = new FileOutputStream(destfile);

        //流的对拷i
        IOUtils.copyBytes(open,fileOutputStream,conf);
    }
}