0x00: 说明
使用 Java 操作 HDFS 文件系统可以使用其对应的Java API,即对应三个 jar 依赖包:
- hadoop-common.jar (该文件在 hadoop-2.10.1.tar.gz 压缩包中的
\share\hadoop\common
目录下) - hadoop-hdfs.jar (该文件在 hadoop-2.10.1.tar.gz 压缩包中的
\share\hadoop\hdfs
目录下) - hadoop-client.jar (该文件在 hadoop-2.10.1.tar.gz 压缩包中的
\share\hadoop\hdfs
目录下)
这三个 jar 包的具体名字可能根据你所安装的版本进行变化,在本文档中这三个文件名称具体如下:
此处我不推荐直接通过 jar 包引入依赖支持,本文中也将不在撰写 jar 的方式引入,因为这三个jar还依赖于其他的依赖库,例如 woodstox-core
等一系列jar包,过程较为繁琐,因此本文中使用 pom 表引入对应配置,使用pom表来管理依赖后,子依赖会自动导入,不在需要我们手动引入,较为方便,pom表依赖配置如下:
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.10.1</version>
</dependency>
在本文中我将在宿主机使用 IDEA 创建对应工程调用虚拟机的 Java API 接口,创建基本 Java 工程在本文中将不在赘述,但请注意,在创建工程时请将系统编译方式选择为 Maven,如下图所示:
0x01: 依赖导入
注意,在第三步引入后你会发现他是处于红色的错误状态,此时点击第四步刷新依赖后即可
引入依赖完成后如下图所示,但因为版本问题存在相对较多的安全的漏洞提示,鼠标放在上方即可显示相关的CVE漏洞编号,但我们仅仅只是学习用途,该问题我们直接忽略
该步骤完成后 pom 表中无红色文本内容时则代表已完成依赖引入
0x02: HDFS 文件创建
这里给出一段示例代码,你可以用来验证 HDFS 的 Java API 是否能正常工作。在开始前,你需要了解如下几个注意点:
- 我们在访问 hdfs 的时候会进行一个权限认证认证的过程,取用户名的过程是这样的:
首先读取 HADOOP_USER_NAME
系统环境变量,如果不为空,那么拿它作用户名
如果为空,则读取 HADOOP_USER_NAME
这个 java 环境变量,如果继续为空,则抛出异常
因此在下方代码中,我在第 19-20 行中加了环境变量配置,如果你不想进行该配置,则可以在第 27 行文件系统配置中进行修改,添加一个user参数,代码如下:
// 链接到文件系统
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.234.129:9000"), conf, "root");
- 该段代码运行后可能会提示有找不到 logger 和 log4j 未正常初始化的配置,如下图,但因为我们此处仅作学习用途,该警告我们可直接忽略。
完整实例代码如下:
package org.example;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;
public class Main {
public static void main(String[] args) {
// 配置环境变量
Properties properties = System.getProperties();
properties.setProperty("HADOOP_USER_NAME", "root");
// 创建配置
Configuration conf = new Configuration();
try {
// 链接到文件系统
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.234.129:9000"), conf);
// 创建文件
FSDataOutputStream fsDataOutputStream = fileSystem.create(new Path("/Tianxidev/test/1.txt"));
// 写入文件内容到输出流
fsDataOutputStream.writeUTF("Hi HDFS!");
// 输出流提交 HDFS
fsDataOutputStream.flush();
// 关闭输出流
fsDataOutputStream.close();
// 关闭文件系统
fileSystem.close();
} catch (IOException | URISyntaxException e) {
throw new RuntimeException(e);
}
}
}
运行后,我们在虚拟机上执行命令 hdfs dfs -ls /
查看 HDFS 文件系统根目录,发现已多出一个我们代码中创建的文件夹,使用 hdfs dfs -cat /Tianxidev/test/1.txt
查看我们创建的文件内容发现写入内容为预期文本,此时则代表 HDFS 的 Java API 工作正常。
0x03: HDFS 文件夹创建
此处仅提供完整样例代码不在提供运行截图,样例代码已经过验证
package org.example;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;
public class Main {
public static void main(String[] args) {
// 配置环境变量
Properties properties = System.getProperties();
properties.setProperty("HADOOP_USER_NAME", "root");
// 创建配置
Configuration conf = new Configuration();
try {
// 链接到文件系统
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.234.129:9000"), conf);
// 创建文件夹
fileSystem.mkdirs(new Path("/Tianxidev/test1"));
// 关闭文件系统
fileSystem.close();
} catch (IOException | URISyntaxException e) {
throw new RuntimeException(e);
}
}
}
0x04: 本地文件上传 HDFS
此处仅提供完整样例代码不在提供运行截图,样例代码已经过验证
package org.example;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;
public class Main {
public static void main(String[] args) {
// 配置环境变量
Properties properties = System.getProperties();
properties.setProperty("HADOOP_USER_NAME", "root");
// 创建配置
Configuration conf = new Configuration();
try {
// 链接到文件系统
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.234.129:9000"), conf);
// 上传本地文件
fileSystem.copyFromLocalFile(new Path("D:\\temp\\hdfs_test_1.txt"),new Path("/Tianxidev/test1"));
// 关闭文件系统
fileSystem.close();
} catch (IOException | URISyntaxException e) {
throw new RuntimeException(e);
}
}
}
0x05: 读取 HDFS 文件内容
此处仅提供完整样例代码不在提供运行截图,样例代码已经过验证
package org.example;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;
public class Main {
public static void main(String[] args) {
// 配置环境变量
Properties properties = System.getProperties();
properties.setProperty("HADOOP_USER_NAME", "root");
// 创建配置
Configuration conf = new Configuration();
try {
// 链接到文件系统
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.234.129:9000"), conf);
// 打开文件
FSDataInputStream fsDataInputStream = fileSystem.open(new Path("/Tianxidev/test/1.txt"));
// 打印文件内容
System.out.println("文件内容: " + fsDataInputStream.readUTF());
// 关闭输入流
fsDataInputStream.close();
// 关闭文件系统
fileSystem.close();
} catch (IOException | URISyntaxException e) {
throw new RuntimeException(e);
}
}
}
0x06: HDFS 文件下载本地
此处仅提供完整样例代码不在提供运行截图,样例代码已经过验证
请注意,因为win系统文件系统结构原因,会抛出如下报错:
java.io.FileNotFoundException: java.io.FileNotFoundException: HADOOP_HOME and hadoop.home.dir are unset.
出现该报错时需要你引入 winutils 支持,winutil.exe 主要用于模拟linux下的目录环境,你可以在互联网上寻找该配置教程,如果你不想麻烦,也可以选择通过 API 读取文件内容然后在使用 Java 文件相关API方法将文件流作为文件写入系统。
package org.example;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;
public class Main {
public static void main(String[] args) {
// 配置环境变量
Properties properties = System.getProperties();
properties.setProperty("HADOOP_USER_NAME", "root");
// 创建配置
Configuration conf = new Configuration();
try {
// 链接到文件系统
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.234.129:9000"), conf);
// 下载文件到本地
fileSystem.copyToLocalFile(new Path("/Tianxidev/test1/hdfs_test_1.txt"),new Path("D:\\temp\\hdfs_test_1.txt"));
// 关闭文件系统
fileSystem.close();
} catch (IOException | URISyntaxException e) {
throw new RuntimeException(e);
}
}
}
0x07: 远程删除 HDFS 文件或文件夹
此处仅提供完整样例代码不在提供运行截图,样例代码已经过验证文章来源:https://uudwc.com/A/1Xdo
package org.example;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;
public class Main {
public static void main(String[] args) {
// 配置环境变量
Properties properties = System.getProperties();
properties.setProperty("HADOOP_USER_NAME", "root");
// 创建配置
Configuration conf = new Configuration();
try {
// 链接到文件系统
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.234.129:9000"), conf);
// b: true 递归删除目录 false 删除指定文件
fileSystem.delete(new Path("/Tianxidev/test1/hdfs_test_1.txt"),false);
fileSystem.delete(new Path("/Tianxidev"),true);
// 关闭文件系统
fileSystem.close();
} catch (IOException | URISyntaxException e) {
throw new RuntimeException(e);
}
}
}
文章来源地址https://uudwc.com/A/1Xdo