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命令行进行测试
出现上面的内容,说明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是域名的倒写。比如域名是·,则GroupId就要写com.baidu.www。
比如这里就写com.zhang。
????????ArtifactId是项目的名称。比如hdfs_api,然后点击Finish
????????打开界面后,jar包会自动导入。留意External Libraries目录。现在maven项目就构建完成了。
这里一般需要:
在java文件夹中编写源码在resources中写项目的配置文件在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://·piler.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>
????????<!--hadoop的java 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>
这些是创建项目时设定的内容。
grouId:公司域名。artifactId:项目名。version:项目版本。properties:全局参数设置,包括:
project.build.sourceEncoding:项目的编码。UTF-8naven.compiler.source:使用jdk版本(Java8)maven.compiler.target:源码编译版本(Java8)hadoop.version:Hadoop版本dependencies:jar包的依赖
dependency:测试的依赖坐标dependency:日志打印依赖坐标dependency:hadoop的通用模块依赖坐标dependency:hadoop对HDFS分布式文件系统访问技术支持的依赖坐标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都有多个选择。这里选择的是:
org.apache.hadoop.conf.Configurationorg.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个。