通过Java实现HDFS操作及访问

1、通过Java实现HDFS操作及访问

接下来使用Java进行HDFS客户端的操作。

①要用Java操作分布式文件系统,首先找到操作文档。

②在hadoop官网Apache Hadoop 上找到版本列表

③进入Apache Hadoop 找到对应的版本。

④进入 Apache Hadoop 找到操作文档

⑤进入 Hadoop – Apache Hadoop 3.1.2 拖到最后,找到Java API docs

⑥进入 Apache Hadoop Main 3.1.2 API 

        这里提供Java操作HDFS的客户端。可以通过Java面向对象的方式,使用类创建对象对分布式文件系统进行操作。

2、IntelliJ IDEA

        安装ideaIU-2018.3.exe、ideaIC-2021.1.exe安装过程略。

        如果需要激活码,可以关注公众号“Java团长”。回复激活码,即可获取。

注意:如果在激活时intellij IDEA激活码出现"this licensee K03CHKJCFT has been cancelled",则需要:

第一步:修改hosts文件

路径为:C:\Windows\System32\drivers\etc\hosts

并将“0**.0.0.0 account.jetbrains.com**”加至最后一行

第二步,打开IDEA,将激活码填入Activation code处即可激活成功。

​​​​​​​3、maven软件安装与配置

①新建项目前,要先做一些准备,比如安装好Java所需的软件。

②确保在cmd输入 javac -version时能出现Java的版本信息。

③另外,需要安装maven软件。

        其中 apache-maven-3.5.2.zip是maven安装包;maven_repository.zip是jar包仓库。

考虑放到不带中文的路径下,直接解压。比如解压到:

D:\software\hdfs\apache-maven-3.5.2         D:\software\hdfs\maven_repository

        编辑 D:\software\hdfs\apache-maven-3.5.2\conf\settings.xml 文件,并修改jar包仓库的路径为前面对应的路径。

  <!-- localRepository

   | The path to the local repository maven will use to store artifacts.

   |

   | Default: ${user.home}/.m2/repository

  <localRepository>/path/to/local/repo</localRepository>

  -->

<localRepository>D:\software\hdfs\maven_repository</localRepository>

这样就完成了maven的配置。

       另外,还要设置环境变量。在系统环境变量中配置MAVEN_HOME为D:\software\hdfs\apache-maven-3.5.2。并把 %MAVEN_HOME%\bin 添加到 PATH 路径中。

并通过cmd命令行进行测试

mvn -v

出现上面的内容,说明maven环境在Windows上已经配置好了。

创建子目录 D:\android\ideaProject_bigData 用于存放工程。

​​​​​​​4、新建maven项目并关联maven插件

        点击Create New Project

        左边选择Maven,使用本地的JDK1.8(必须1.8),注意不要勾上Create from archetype。然后点击Next

        设置在哪个路径下安装hdfs_api。比如说放到刚才创建的D:\android\ideaProject_bigData目录。项目名跟文件夹名称最好一致。

GroupId是域名的倒写。比如域名是www.baidu.com,则GroupId就要写com.baidu.www。

比如这里就写com.zhang。

        ArtifactId是项目的名称。比如hdfs_api,然后点击Finish

        打开界面后,jar包会自动导入。留意External Libraries目录。现在maven项目就构建完成了。

这里一般需要:

  1. 在java文件夹中编写源码
  2. 在resources中写项目的配置文件
  3. 在test目录下做一些测试。

        配置Maven。打开File——Settings,找到Build, Execution, Deployment——Build Tools——Maven,设置maven的依赖目录,注意修改settings file后,Local repository会自动检测到修改过的本地仓库路径的。

接下来导入项目所需要的依赖。

5、导入项目所需要的依赖

把下面的内容拷贝到 pom.xml 文件中。(通常只需要替换properties部分)

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zhang</groupId>

    <artifactId>hdfs_api</artifactId>

    <version>1.0-SNAPSHOT</version>

    <properties>

        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <maven.compiler.source>1.8</maven.compiler.source>

        <maven.compiler.target>1.8</maven.compiler.target>

        <hadoop.version>3.1.2</hadoop.version>

    </properties>

    <!--jar包的依赖-->

    <dependencies>

        <!--测试的依赖坐标-->

        <dependency>

            <groupId>junit</groupId>

            <artifactId>junit</artifactId>

            <version>4.11</version>

        </dependency>

        <!--日志打印的依赖坐标-->

        <dependency>

            <groupId>org.apache.logging.log4j</groupId>

            <artifactId>log4j-core</artifactId>

            <version>2.8.2</version>

        </dependency>

        <!--hadoopjava api的依赖坐标-->

        <dependency>

            <groupId>org.apache.hadoop</groupId>

            <artifactId>hadoop-common</artifactId>

            <version>${hadoop.version}</version>

        </dependency>

        <!--hadoop的对HDFS分布式文件系统访问的技术支持的依赖坐标-->

        <dependency>

            <groupId>org.apache.hadoop</groupId>

            <artifactId>hadoop-hdfs</artifactId>

            <version>${hadoop.version}</version>

        </dependency>

        <dependency>

            <groupId>org.apache.hadoop</groupId>

            <artifactId>hadoop-client</artifactId>

            <version>${hadoop.version}</version>

        </dependency>

    </dependencies>

</project>

这些是创建项目时设定的内容。

  1. grouId:公司域名。
  2. artifactId:项目名。
  3. version:项目版本。
  4. properties:全局参数设置,包括:
    1. project.build.sourceEncoding:项目的编码。UTF-8
    2. naven.compiler.source:使用jdk版本(Java8)
    3. maven.compiler.target:源码编译版本(Java8)
    4. hadoop.version:Hadoop版本
  5. dependencies:jar包的依赖
    1. dependency:测试的依赖坐标
    2. dependency:日志打印依赖坐标
    3. dependency:hadoop的通用模块依赖坐标
    4. dependency:hadoop对HDFS分布式文件系统访问技术支持的依赖坐标
    5. dependency:hadoop客户端访问依赖坐标

        配置好这些以后,在2020.1之前的版本会自动导入相关的jar包。但在2020.1后的版本,为防止pom更新时,MAVEN自动导包时卡死的问题,取消了自动导包机制。而是增加了导入按钮的快捷键。

        当修改了maven依赖后,当前pom文件右上角会出现一个maven小图标;点一下该图标即可更新依赖。生成的依赖包;这些jar包就是从jar包仓库maven_repository中来的。如果发现依赖坐标的地方出现红色,或者导入不完整,可以检查一下配置的路径,看是否正确。其中,jar包是人家给你写好的一些代码,并打包给你。有了这些jar包,就可以进行调用,比如junit测试。

6、编写Java代码——向HDFS文件系统创建文件夹

        在src/main/java 目录下新建 package,目的为了让代码更好的分类。假设package名称为com.zhang。

        创建类HdfsClientAppTest。

        话说写个psvm,然后按一下Tab键,就可以生成

    public static void main(String[] args) {
    
    }

src/main/java/com/zhang/HdfsClientAppTest.java

package com.zhang;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.fs.*;

import org.junit.Test;

import java.io.IOException;

import java.net.URI;

/**

 *

 */

public class HdfsClientAppTest {

    public static void main(String[] args) throws IOException {

        //向HDFS文件系统创建文件夹

        //1.新建一个Configuration对象

        //idea的智能提示alt + enter

        Configuration configuration = new Configuration();

        configuration.set("fs.defaultFS","hdfs://192.168.110.101:8020");

        //2.获取FileSystem对象

        FileSystem fileSystem = FileSystem.get(configuration);

        fileSystem.mkdirs(new Path("/100_3"));

        //3.关闭资源

        fileSystem.close();

    }

注意使用的类,Configuration和FileSystem都有多个选择。这里选择的是:

  1. org.apache.hadoop.conf.Configuration
  2. org.apache.hadoop.fs.FileSystem

        另外,100_3是在分布式文件系统中创建的文件夹。

        启动分布式文件系统。使用上面的java代码往分布式文件系统中创建文件夹100_3。

        另外,拷贝 log4j.properties文件到src/main/resources目录下。

        在IDEA上运行该程序。执行完毕后可以在 http://192.168.110.101:50070/explorer.html 中看到100_3的目录了。

注意:运行Java程序时,如果出现

参考:maven hadoop 3.x HADOOP_HOME and hadoop.home.dir are unset Not implemented by the WebHdfsFileSystem FileSystem implementation - tele - 博客园 

如果下载的过程中出现了 HADOOP_HOME and hadoop.home.dir are unset,那么就说明你没有配置windows本地的hadoop环境变量.你可能会想我是远程调用linux下的hadoop,与我本地的hadoop有什么关系?如果你的操作只对远程的hadoop生效,如上传,创建目录,文件改名(写)等那么你是不需要在windows本地配置hadoop的,可一旦涉及到下载(读),hadoop内部的缓存机制要求本地也必须有hadoop,于是也会出现HADOOP_HOME and hadoop.home.dir are unset,解决办法配置HADOOP_HOME并加入%HADOOP_HOME%\bin到PATH中,之后测试下hadoop version命令,有效的话重启你的eclipse/myeclipse,但这还不够,windows下的hadoop还需要winutils.exe,否则会报Could not locate Hadoop executable: xxxx\winutils.exe

可以在GitHub - steveloughran/winutils: Windows binaries for Hadoop versions (built from the git commit ID used for the ASF relase) 下载winutils,找hadoop-3.0.0的。

        先把原来的hadoop-3.1.2.tar.gz在Windows上解压,得到 D:\software\hdfs\hadoop-3.1.2 目录。并把该路径设置到环境变量HADOOP_HOME中。

         再把 %HADOOP_HOME%\bin 添加到环境变量 PATH 中。

        然后拷贝 winutils\hadoop-3.0.0\bin\winutils.exe 文件到这个bin目录下。

        另外,也可以通过如下代码往HDFS文件系统中创建文件夹

    @Test

    public void getHdfsClient2() throws Exception {

        //向HDFS文件系统创建文件夹

        //1.新建一个Configuration对象

        //idea的智能提示alt + enter

        Configuration configuration = new Configuration();

        FileSystem fileSystem = FileSystem.get(

                new URI("hdfs://192.168.110.101:8020"),

                configuration,

                "root"

        );

        fileSystem.mkdirs(new Path("/100_2"));

        fileSystem.close();

    }

        在IDEA上运行该程序。执行完毕后可以在 http://192.168.110.101:50070/explorer.html 中看到100_2的目录了。

7、编写Java代码——文件上传

通过如下代码往HDFS文件系统中上传文件(假设本地文件为d:\tmp\hello.txt,上传到HDFS的/100_1/目录下,注意该目录原本并不存在)

    /**

     * 实现一个文件的上传

     */

    @Test

    public void putFileToHDFS() throws Exception {

        //向HDFS文件系统创建文件夹

        //1.新建一个Configuration对象

        //idea的智能提示alt + enter

        Configuration configuration = new Configuration();

        FileSystem fileSystem = FileSystem.get(

                new URI("hdfs://192.168.110.101:8020"),

                configuration,

                "root"

        );

        Path srcPath = new Path("D:\\tmp\\hello.txt");

        Path destPath = new Path("/100_1/hello.txt");

        fileSystem.copyFromLocalFile(srcPath,destPath);

        fileSystem.close();

        

    }

点击100_1进入后目录后

    /**

     * 伪造用户,实现一个文件的上传

     */

    @Test

    public void putFileToHDFS2() throws Exception {

        //向HDFS文件系统创建文件夹

        //1.新建一个Configuration对象

        //idea的智能提示alt + enter

        Configuration configuration = new Configuration();

        FileSystem fileSystem = FileSystem.get(

                new URI("hdfs://192.168.110.101:8020"),

                configuration,

                "zhang"

        );

        Path srcPath = new Path("D:\\tmp\\hello.txt");

        Path destPath = new Path("/100_1/hello2.txt");

        fileSystem.copyFromLocalFile(srcPath,destPath);

        fileSystem.close();

    }

    /**

     * 设置副本数,实现一个文件的上传

     */

    @Test

    public void putFileToHDFS3() throws Exception {

        //向HDFS文件系统创建文件夹

        //1.新建一个Configuration对象

        //idea的智能提示alt + enter

        Configuration configuration = new Configuration();

        configuration.set("dfs.replication","2");

        FileSystem fileSystem = FileSystem.get(

                new URI("hdfs://192.168.110.101:8020"),

                configuration,

                "zhang"

        );

        Path srcPath = new Path("D:\\tmp\\hello.txt");

        Path destPath = new Path("/100_2/hello3.txt");

        fileSystem.copyFromLocalFile(srcPath,destPath);

        fileSystem.close();

    }

}

​​​​​​​8、编写Java代码——删除文件夹

    /**

     * 删除文件夹

     */

    @Test

    public void deleteAtHDFS() throws Exception {

        //向HDFS文件系统创建文件夹

        //1.新建一个Configuration对象

        //idea的智能提示alt + enter

        Configuration configuration = new Configuration();

        configuration.set("dfs.replication","2");

        FileSystem fileSystem = FileSystem.get(

                new URI("hdfs://192.168.110.101:8020"),

                configuration,

                "zhang"

        );

        fileSystem.delete(new Path("/100_3"),true);

        fileSystem.close();

    }

删除前和删除后对比

​​​​​​​9、编写Java代码——重命名文件

    @Test

    public void renameAtHDFS() throws Exception {

        //向HDFS文件系统创建文件夹

        //1.新建一个Configuration对象

        //idea的智能提示alt + enter

        Configuration configuration = new Configuration();

        configuration.set("dfs.replication","2");

        FileSystem fileSystem = FileSystem.get(

                new URI("hdfs://192.168.110.101:8020"),

                configuration,

                "zhang"

        );

        fileSystem.rename(new Path("/100_2/hello3.txt"),new Path("/100_2/hello4.txt"));

        fileSystem.close();

    }

重命名前与重命名后对比

​​​​​​​10、编写Java代码——遍历文件夹​​​​​​​

    /**

     * 遍历文件,获取所有文件信息

     */

    @Test

    public void readListAtHDFS() throws Exception {

        //向HDFS文件系统创建文件夹

        //1.新建一个Configuration对象

        //idea的智能提示alt + enter

        Configuration configuration = new Configuration();

        configuration.set("dfs.replication", "2");

        FileSystem fileSystem = FileSystem.get(

                new URI("hdfs://192.168.110.101:8020"),

                configuration,

                "root"

        );

        RemoteIterator<LocatedFileStatus> iterator = fileSystem.listFiles(new Path("/"), true);

        while (iterator.hasNext()) {

            LocatedFileStatus fileStatus = iterator.next();

            System.out.println("权限=" + fileStatus.getPermission());

            System.out.println("文件名" + fileStatus.getPath().getName());

            System.out.println("文件大小=" + fileStatus.getLen());

            System.out.println("文件副本数=" + fileStatus.getReplication());

            //获取块的位置信息

            BlockLocation[] blockLocations = fileStatus.getBlockLocations();

            for (BlockLocation blockLocation : blockLocations) {

                System.out.println("块的偏移量=" + blockLocation.getOffset());

                System.out.println("块大小=" + blockLocation.getLength());

                String hosts[] = blockLocation.getHosts();

                for (String host : hosts) {

                    System.out.println("副本存储的主机位置=" + host);

                }

                System.out.println("块信息---------------");

            }

            System.out.println("文件信息-----------------------------");

        }

        fileSystem.close();

    }

}

留意终端的输出结果

注意hello4.txt的副本是2个。

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Distantfbc

你的鼓励是我最大的动力,谢谢

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

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

打赏作者

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

抵扣说明:

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

余额充值