之前学习了HDFS的shell操作,但那是在集群内部操作,在生产环境下我们不是每次都在内部进行操作,我们是使用客户端连接集群进行操作,通过window客户端连接集群进行操作,称为API操作。
1 环境准备
因为在window环境下,所以需要安装相应的hadoop文件
(1)将hadoop-3.1.0拷贝到一个非中文路径中
(2)配置HADOOP_HOME路径
路径为hadoop-3.10的路径
(3)配置Path环境变量
2 API操作
(1)创建项目
在IDEA中创建一个Maven工程HdfsClientDemo,并导入相应的依赖坐标+日志添加
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.30</version>
</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
创建包名:com.atguigu.hdfs
创建HdfsClient类
(2)API主要操作
用法都写在代码中了
package com.jiaran.hdfs;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.checkerframework.common.value.qual.StaticallyExecutable;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
public class HdfsClient {
private FileSystem fs;//文件系统,相当于一个连接
@Before //先执行
public void init() throws URISyntaxException, IOException, InterruptedException { //初始化方法
//一个配置文件对象
Configuration configuration = new Configuration();
configuration.set("dfs.replication", "2");
String user = "jiaran";
URI uri = new URI("hdfs://hadoop102:8020");
fs = FileSystem.get(uri, configuration, user);
}
@After //最后执行
public void close() throws IOException {
// 3关闭资源
fs.close();
}
//API操作:创建目录
@Test
public void testMkdirs() throws IOException, URISyntaxException, InterruptedException {
// 2 创建目录
fs.mkdirs(new Path("/xiyou/huaguoshan/"));
}
//API操作:上传
@Test
public void testPut() throws IOException {
// 参数解析: 1表示删除 2 表示覆盖 3 原数据路径 4 目的路径
fs.copyFromLocalFile(false, true, new Path("D:\\sunwukong.txt"), new Path("hdfs://hadoop102/xiyou/huaguoshan"));
}
//API操作:下载
@Test
public void testGet() throws IOException {
//参数解析:是否删除元数据 2 :原数据路径 ,3 目的路径
fs.copyToLocalFile(false, new Path("hdfs://hadoop102/xiyou/huaguoshan/sunwukong.txt"), new Path("D:\\sunwukong2.txt"), false);
}
//API操作:删除
@Test
public void testRM() throws IOException {
//参数解析: 1 参数路径 2 是否递归删除
fs.delete(new Path("/jdk-8u212-linux-x64.tar.gz"), false);
}
//API操作:文件/目录的更名和移动(两个功能同时实现)
@Test
public void testmv() throws IOException {
//参数解析:1 :原文件入境 2 :目的文件路径
fs.rename(new Path("/wcinput/word.txt"), new Path("/wcinput/vtuber.txt"));
}
//API操作:获取文件详情
@Test
public void fileDetail() throws IOException {
//参数解析:1 文件路径 2 是否递归
RemoteIterator<LocatedFileStatus> locatedFileStatusRemoteIterator = fs.listFiles(new Path("/"), true); //获取一个文件迭代器
while (locatedFileStatusRemoteIterator.hasNext()) { //迭代遍历
LocatedFileStatus next = locatedFileStatusRemoteIterator.next();
System.out.println("======== " + next.getPath() + " =========");
System.out.println(next.getPermission());
System.out.println(next.getOwner());
System.out.println(next.getGroup());
System.out.println(next.getLen());
System.out.println(next.getModificationTime());
System.out.println(next.getReplication());
System.out.println(next.getBlockSize());
System.out.println(next.getPath().getName());
//获取块信息
BlockLocation[] blockLocations = next.getBlockLocations();
System.out.println(Arrays.toString(blockLocations));
}
}
// API操作:判断文件夹还是文件
@Test
public void testFile() throws IOException {
//参数解析:路径
FileStatus[] fileStatuses = fs.listStatus(new Path("/"));
for (FileStatus status : fileStatuses) {
if (status.isFile()) {
System.out.println("文件: " + status.getPath().getName());
} else {
System.out.println("目录: " + status.getPath().getName());
}
}
}
}