HDFS的API操作(通过springboot实现)

前言:

此博客为博主学习总结,博主是在windows下编程并运行代码对虚拟机中的hadoop集群进行操作。主体内容为讲述如何使用HDFS API对HDFS分布式文件系统进行操作,若有不足之处,本人很愿意得到各位大佬们的指点。

由于是在windows环境下运行代码,所以需要对java的System.setPropety的用法有简单了解

/**
     * System.setProperty的用法 简言之等同于 配置环境变量
     * 设置指定键对值的系统属性
     * setProperty (String prop, String value);
     *
     * 参数:
     * prop - 系统属性的名称。
     * value - 系统属性的值。
     *
     * 返回:
     * 系统属性以前的值,如果没有以前的值,则返回 null。
     *
     * 抛出:
     * SecurityException - 如果安全管理器存在并且其 checkPermission 方法不允许设置指定属性。
     * NullPointerException - 如果 key 或 value 为 null。
     * IllegalArgumentException - 如果 key 为空。
     * 注:这里的system,系统指的是 JRE (runtime)system,不是指 OS。
     *
     */

hadoop windows依赖文件下载

主体:

1.新建一个springboot项目,pom.xml依赖文件如下所示

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.hadoop</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>hadoop</name>
    <description>hadoop</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--配置hadoop相关依赖-->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>3.1.2</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>javax.servlet</groupId>
                    <artifactId>servlet-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>3.1.2</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>javax.servlet</groupId>
                    <artifactId>servlet-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2.介绍HDFS的Java API和利用API编程的基本步骤
1)org.apache.hadoop.fs.FileSystem
 是一个通用的文件系统API,提供了不同文件系统的统一访问方式。
2)org.apache.hadoop.fs.Path
 是Hadoop文件系统中统一的文件或目录描述,类似于java.io.File对本地文件系统的文件或目录描述。
3)org.apache.hadoop.conf.Configuration
 实现Iterable<Entry<String, String>>, Writable两个接口,读取、解析配置文件(如core-site.xml/hdfs-default.xml/hdfs-site.xml等),或添加配置的工具类
4)org.apache.hadoop.fs.FSDataOutputStream
 对Hadoop中数据输出流的统一封装
5)org.apache.hadoop.fs.FSDataInputStream
 对Hadoop中数据输入流的统一封装

编程基本步骤:
 1)构建Configuration对象,读取并解析相关配置文件
    Configuration configuration = new Configuration();  
  2)设置相关属性
    configuration.set(“fs.defaultFS”,“hdfs://192.168.56.100:9000”);
    configuration.set(“hadoop.user”,“hduser”);
  3)获取特定文件系统实例fs(以HDFS文件系统实例)
    FileSystem fs=FileSystem.get(new URI(“hdfs://192.168.56.100:9000”),configuration,“hduser");
  4)通过文件系统实例fs进行文件操作(以新建文件夹为例)
    fs.mkdirs(new Path("/dir"));

3.在测试类编写操控HDFS相关操作的代码

/**
     * 获取FileSystem,并创建文件夹
     * @throws URISyntaxException
     * @throws IOException
     */
    @Test
    public void getFileSystem() throws URISyntaxException, IOException, InterruptedException {
        //指定hadoop windows依赖文件地址
        System.setProperty("hadoop.home.dir", "D:\\Hadoop\\winutils-master\\hadoop-2.6.0");
        //1.获取文件系统
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.56.100:9000"), configuration,"hduser");
            boolean b = fs.mkdirs(new Path("/dir"));
            fs.close();
        System.out.println("创建文件夹是否成功:"+b);
    }
    
 	/**
     * 遍历输出FileSystem的所有文件名称
     * @throws Exception
     */
    @Test
    public void listAllFiles()throws Exception{
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.56.100:9000"), new Configuration());
        //获取RemoteIterator 得到所有的文件或者文件夹,第一个参数指定遍历的路径,第二个参数表示是否要递归遍历
        RemoteIterator<LocatedFileStatus> locatedFileStatusRemoteIterator = fileSystem.listFiles(new Path("/"), true);
        while (locatedFileStatusRemoteIterator.hasNext()){
            LocatedFileStatus next = locatedFileStatusRemoteIterator.next();
            System.out.println(next.getPath().toString());
        }
        fileSystem.close();
    }


	/**
     * 删除hdfs的指定路径的文件
     */
    @Test
    public void removeFiles() throws IOException, URISyntaxException {
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.56.100:9000"),new Configuration(),"hduser");
        fs.delete(new Path("/dir.txt"),true);
    }


    /**
     * 上传文件
     * 提示:FileSystem fs = FileSystem.get(new URI("hdfs://192.168.56.100:9000"),new Configuration()); 
     * 由于windows下的用户和linux下的用户不一致,只有读取hdfs的权限,无法上传文件
     * 解决办法:FileSystem fs = FileSystem.get(new URI("hdfs://192.168.56.100:9000"),new Configuration(),"hduser");
     * 或者对hdfs-site.xml修改,将dfs.permissions修改为False,使权限释放,
     * @throws URISyntaxException
     * @throws IOException
     */
    @Test
    public void uploadByCopy() throws URISyntaxException, IOException, InterruptedException {
        System.setProperty("hadoop.home.dir", "D:\\Hadoop\\winutils-master\\hadoop-2.6.0");
        //1.获取文件系统
        Configuration configuration = new Configuration();
//跨平台提交        configuration.setBoolean("mapreduce.app-submission.cross-platform",true);
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.56.100:9000"), configuration,"hduser");
        //2.执行操作 上传文件
        fs.copyFromLocalFile(new Path("file:///d:\\GZH\\Desktop\\input\\input.txt"),new Path("/dir1/dir2"));
        //关闭资源
        fs.close();
        System.out.println("结束!");
    }

    /**
     * 下载文件
     * error:java.io.IOException: Incomplete HDFS URI, no host: hdfs://192.168.56.100.9000
     * 由于windows有防火墙导致无法下载至windows系统
     * @throws URISyntaxException
     * @throws IOException
     */
    @Test
    public void downloadByCopy() throws URISyntaxException, IOException {
        System.setProperty("hadoop.home.dir", "D:\\Hadoop\\winutils-master\\hadoop-2.6.0");
        //1.获取文件系统
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.56.100.9000"), configuration);
        //2.执行操作 下载文件
        fs.copyToLocalFile(true,new Path("/dir1/dir2/file1.txt"), new Path("D:\\GZH\\Desktop\\output"));
        //关闭资源
        fs.close();
        System.out.println("结束!");
    }


    /**
     * io流方式上传
     * @throws URISyntaxException
     * @throws IOException
     */
    @Test
    public void uploadByIo() throws URISyntaxException, IOException {
        System.setProperty("hadoop.home.dir", "D:\\Hadoop\\winutils-master\\hadoop-2.6.0");
        //1.获取文件系统
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.56.100:9000"), configuration);
        //2.获取输入流   从本地文件系统到hdfs
        FileInputStream fis = new FileInputStream(new File("D:\\GZH\\Desktop\\input\\MD5.txt"));
        //3.获取输出流
        FSDataOutputStream fos = fs.create(new Path("/dir.txt"));
        //4.流的拷贝
        IOUtils.copyBytes(fis,fos,configuration);
        //5.关闭资源
        IOUtils.closeStream(fis);
        IOUtils.closeStream(fos);
        System.out.println("结束!");
    }

    /**
     * io流方式下载
     * error:java.io.FileNotFoundException: D:\GZH\Desktop\output (拒绝访问。)
     * solution:windows端由于防火墙的存在导致无法下载
     * @throws URISyntaxException
     * @throws IOException
     */
    @Test
    public void downloadByIo() throws URISyntaxException, IOException {
        System.setProperty("hadoop.home.dir", "D:\\Hadoop\\winutils-master\\hadoop-2.6.0");
        //1.获取文件系统
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.56.100:9000"), configuration);
        //2.获取输入流
        FSDataInputStream fis = fs.open(new Path("/dir"));
        //3.获取输出流
        FileOutputStream fos = new FileOutputStream(new File("D:\\GZH\\Desktop\\output"));
        //4.流的拷贝
        IOUtils.copyBytes(fis,fos,configuration);
        //5.关闭资源
        IOUtils.closeStream(fis);
        IOUtils.closeStream(fos);
        System.out.println("结束!");
    }
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

易霭珞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值