HDFS常用API

创建一个Maven工程,导入相应的依赖坐标和日志添加,我这里hadoop的版本为2.7.2

<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-core</artifactId>
			<version>2.8.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.hadoop</groupId>
			<artifactId>hadoop-common</artifactId>
			<version>2.7.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.hadoop</groupId>
			<artifactId>hadoop-client</artifactId>
			<version>2.7.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.hadoop</groupId>
			<artifactId>hadoop-hdfs</artifactId>
			<version>2.7.2</version>
		</dependency>
		<dependency>
			<groupId>jdk.tools</groupId>
			<artifactId>jdk.tools</artifactId>
			<version>1.8</version>
			<scope>system</scope>
			<systemPath>${JAVA_HOME}/lib/tools.jar</systemPath>
		</dependency>
</dependencies>

在项目的src/main/resources目录下,新建一个文件,命名为“log4j.properties”,在文件中填入

log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spring.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

启动集群

1.常用API

1.创建目录

 public static void main(String[] args) throws IOException,Exception,URISyntaxException {
        //1 获取hdfs客户端
        Configuration conf = new Configuration();

        //配置在集群上运行 hdfs://主节点名称:9000,"master"为所属用户
        FileSystem fs = FileSystem.get(new URI("hdfs://master:9000"),conf,"master");

        //2 在hdfs上创建路径
        fs.mkdirs(new Path("/0316/dashen/banzhang"));

        //3 关闭资源
        fs.close();
        System.out.println("OVER");
    }

在web端查看结果
在这里插入图片描述

2.文件上传

 //文件上传
    @Test
    public void testCopyFromLocalFile() throws IOException,InterruptedException,URISyntaxException{

        //1 获取fs对象 hdfs://主节点名称:9000,"master"为所属用户
        Configuration conf = new Configuration();      
        FileSystem fs;
        fs = FileSystem.get(new URI("hdfs://master:9000"),conf,"master");

        //2 执行上传文件API 第一个路径为本地文件所在路径,第二个为要上传到的路径
        fs.copyFromLocalFile(new Path("D:\\idea project\\hdfs\\banzhang.txt"),new Path("/0316/dashen/banzhang/banzhang.txt"));

        //3 关闭资源
        fs.close();
        System.out.println("OVER AGAIN");
    }

在web端查看结果
在这里插入图片描述
注意这里的副本数为3,但我一共有四台结点,为什么只上传到了三个节点上呢,这就和参数优先级有关系

测试参数优先级

将hdfs-site.xml拷贝到项目的根目录下,设置副本数为4个
在这里插入图片描述

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

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

删除刚上传的文件,再次上传,看一下副本数是否有变化

[root@master hadoop-2.7.2]# hadoop fs -rm /0316/dashen/banzhang/banzhang.txt
20/04/04 17:06:06 INFO fs.TrashPolicyDefault: Namenode trash configuration: Deletion interval = 0 minutes, Emptier interval = 0 minutes.
Deleted /0316/dashen/banzhang/banzhang.txt

变为了4,和配置文件里设置的一样,所以能得到用户自定义配置文件 >服务器的默认配置(3个)
在这里插入图片描述
我们再在代码中添加conf.set("dfs.replication", "2");将文件再次上传并命名为banwei.txt,可以看到副本数变成了2

    @Test
    public void testCopyFromLocalFile() throws IOException,InterruptedException,URISyntaxException{

        //1 获取fs对象
        Configuration conf = new Configuration();
        conf.set("dfs.replication", "2");
        FileSystem fs;
        fs = FileSystem.get(new URI("hdfs://master:9000"),conf,"master");

        //2 执行上传文件API
        fs.copyFromLocalFile(new Path("D:\\idea project\\hdfs\\banzhang.txt"),new Path("/0316/dashen/banzhang/banwei.txt"));

        //3 关闭资源
        fs.close();
        System.out.println("OVER AGAIN");
    }

在这里插入图片描述
最后可得结论:客户端代码中设置的值 >用户自定义配置文件 >服务器的默认配置(3)

3.文件下载

//文件下载
    @Test
    public void testCopyToLocalFile() throws IOException,InterruptedException,URISyntaxException{

        //1 获取对象
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://master:9000"),conf,"master");

        //2 执行下载操作
        // 第一个参数 boolean delSrc 指是否将原文件删除
        // 第二个参数 Path src 指要下载的文件路径
        // 第三个参数 Path dst 指将文件下载到的路径
        // 第四个参数 boolean useRawLocalFileSystem 是否开启文件校验
        fs.copyToLocalFile(false,new Path("/0316/dashen/banzhang/banzhang.txt"),new Path("f:/HDFStest/banzhang.txt"),true);

        //3 关闭资源
        fs.close();
        System.out.println("OVER AGAIN AGAIN");
    }

在本地查看结果
在这里插入图片描述

4.文件夹删除

// 文件/文件夹删除
    @Test
    public void testDelete() throws IOException,InterruptedException,URISyntaxException{
        //1 对象获取
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://master:9000"),conf,"master");

        //2 删除对象
        //第二个参数为是否递归删除,文件无所谓,文件夹必须为true
        fs.delete(new Path("/0316"),true);

        //3 关闭资源
        fs.close();
        System.out.println("OVER AAAA");
    }

在web端查看结果,可以发现/0316文件夹已经被删除
在这里插入图片描述

5.文件更名

先上传一个文件到根目录[root@master hadoop-2.7.2]# hadoop fs -put liubei.txt /

//文件更名
    @Test
    public void testRename() throws IOException,InterruptedException,URISyntaxException{
        //1 获取对象
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://master:9000"),conf,"master");

        //2 执行更名操作
        fs.rename(new Path("/liubei.txt"),new Path("/yanjing.txt"));

        //3 关闭资源
        fs.close();
        System.out.println("OVER AAAAA");
    }

在web端查看结果
在这里插入图片描述

6.文件详情查看

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

   //查看文件
    @Test
    public void testListFiles()throws IOException,InterruptedException,URISyntaxException{

        //1 获取对象
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://master:9000"),conf,"master");

        //2 执行操作
        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("----------分割线----------");
        }

        // 3 关闭资源
        fs.close();
    }

在终端查看结果
在这里插入图片描述

6.判断文件和文件夹

 //判断是文件还是文件夹
    @Test
    public void testListStatus() throws IOException, InterruptedException, URISyntaxException{

        // 1 获取文件配置信息
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://master:9000"), configuration, "master");

        // 2 判断是文件还是文件夹
        FileStatus[] listStatus = fs.listStatus(new Path("/"));
        for (FileStatus fileStatus : listStatus) {
            // 如果是文件
            if (fileStatus.isFile()) {
                System.out.println("文件: "+fileStatus.getPath().getName());
            }else {
                System.out.println("文件夹: "+fileStatus.getPath().getName());
            }
        }

        // 3 关闭资源
        fs.close();
    }

在终端查看结果
在这里插入图片描述

2.完整代码

package com.atguigu.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.junit.Test;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

public class HDFSClient {
    public static void main(String[] args) throws IOException,Exception,URISyntaxException {
        //1 获取hdfs客户端
        Configuration conf = new Configuration();

        //配置在集群上运行
        FileSystem fs = FileSystem.get(new URI("hdfs://master:9000"),conf,"master");

        //2 在hdfs上创建路径
        fs.mkdirs(new Path("/0316/dashen/banzhang"));

        //3 关闭资源
        fs.close();
        System.out.println("OVER");
    }

    //1 文件上传
    @Test
    public void testCopyFromLocalFile() throws IOException,InterruptedException,URISyntaxException{

        //1 获取fs对象
        Configuration conf = new Configuration();
        conf.set("dfs.replication", "2");
        FileSystem fs;
        fs = FileSystem.get(new URI("hdfs://master:9000"),conf,"master");

        //2 执行上传文件API
        fs.copyFromLocalFile(new Path("D:\\idea project\\hdfs\\banzhang.txt"),new Path("/0316/dashen/banzhang/banwei.txt"));

        //3 关闭资源
        fs.close();
        System.out.println("OVER AGAIN");
    }

    //2 文件下载
    @Test
    public void testCopyToLocalFile() throws IOException,InterruptedException,URISyntaxException{

        //1 获取对象
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://master:9000"),conf,"master");

        //2 执行下载操作
        // boolean delSrc 指是否将原文件删除
        // Path src 指要下载的文件路径
        // Path dst 指将文件下载到的路径
        // boolean useRawLocalFileSystem 是否开启文件校验
        //fs.copyToLocalFile(new Path("/banhua.txt"),new Path("f:/HDFStest/banhua.txt"));
        fs.copyToLocalFile(false,new Path("/0316/dashen/banzhang/banzhang.txt"),new Path("f:/HDFStest/banzhang.txt"),true);

        //3 关闭资源
        fs.close();
        System.out.println("OVER AGAIN AGAIN");
    }

    // 3 文件删除
    @Test
    public void testDelete() throws IOException,InterruptedException,URISyntaxException{
        //1 对象获取
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://master:9000"),conf,"master");

        //2 删除对象
        //第二个参数为是否递归删除,文件无所谓,文件夹必须为true
        fs.delete(new Path("/0316"),true);

        //3 关闭资源
        fs.close();
        System.out.println("OVER AAAA");
    }

    //4 文件更名
    @Test
    public void testRename() throws IOException,InterruptedException,URISyntaxException{
        //1 获取对象
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://master:9000"),conf,"master");

        //2 执行更名操作
        fs.rename(new Path("/liubei.txt"),new Path("/yanjing.txt"));

        //3 关闭资源
        fs.close();
        System.out.println("OVER AAAAA");
    }

    //5 查看文件
    @Test
    public void testListFiles()throws IOException,InterruptedException,URISyntaxException{

        //1 获取对象
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://master:9000"),conf,"master");

        //2 执行操作
        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("----------分割线----------");
        }

        // 3 关闭资源
        fs.close();
    }

    //6 判断是文件还是文件夹
    @Test
    public void testListStatus() throws IOException, InterruptedException, URISyntaxException{

        // 1 获取文件配置信息
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://master:9000"), configuration, "master");

        // 2 判断是文件还是文件夹
        FileStatus[] listStatus = fs.listStatus(new Path("/"));
        for (FileStatus fileStatus : listStatus) {
            // 如果是文件
            if (fileStatus.isFile()) {
                System.out.println("文件: "+fileStatus.getPath().getName());
            }else {
                System.out.println("文件夹: "+fileStatus.getPath().getName());
            }
        }

        // 3 关闭资源
        fs.close();
    }
}
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐