之前,一直通过Linux命令操作HDFS。接下来,在本地配置HDFS客户端,通过编写代码操作HDFS。
环境:
- mbp2018
- hadoop-2.7.7
配置步骤
1. 在本地解压hadoop-2.7.7.tar.gz,并配置环境变量。在终端输入$ hadoop
测试是否安装成功。
2. 在IDEA中建立一个空的mavean工程。
File new Projects
一路确定即可
3. 打开工程中的pox.xml文件,在pom.xml文件中加入如下内容:
4.0.0
com.bigdata
hadoop100
1.0-SNAPSHOT
junit
junit
RELEASE
org.apache.logging.log4j
log4j-core
2.8.2
org.apache.hadoop
hadoop-common
2.7.7
org.apache.hadoop
hadoop-client
2.7.7
org.apache.hadoop
hadoop-hdfs
2.7.7
联网后,等待所有依赖导入完成。导入成功的包颜色会是白的,否则应该是灰色或者黄色。
4. 在工程的resources目录中加入log4j.properties文件,并写入如下内容:
log4j.rootLogger=INFO,stdout,debug,error
#输出到控制台
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %p [%t] %C.%M(%L) | %m%n
#输出DEBUG级别以上的日志到文件
log4j.appender.debug=org.apache.log4j.DailyRollingFileAppender
log4j.appender.debug.layout=org.apache.log4j.PatternLayout
log4j.appender.debug.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %p [%t] %C.%M(%L) | %m%n
log4j.appender.debug.File=./logs/debug.txt
log4j.appender.debug.DatePattern=','yyyy-MM-dd
log4j.appender.debug.Threshold=DEBUG
log4j.appender.debug.Append=true
log4j.appender.debug.Encoding=UTF-8
#输出DEBUG级别以上的日志到文件
log4j.appender.error=org.apache.log4j.DailyRollingFileAppender
log4j.appender.error.layout=org.apache.log4j.PatternLayout
log4j.appender.error.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %p [%t] %C.%M(%L) | %m%n
log4j.appender.error.File=./logs/error.txt
log4j.appender.error.DatePattern=','yyyy-MM-dd
log4j.appender.error.Threshold=ERROR
log4j.appender.error.Append=true
log4j.appender.error.Encoding=UTF-8
5. 新建一个JavaClass文件,准备测试客户端是否创建成功
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.junit.Test;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class HDFSClient {
public FileSystem getConf(){
Configuration conf = new Configuration();
FileSystem fs = null;
try {
fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), conf, "lg"); // 以用户lg连接hdfs://hadoop102:9000,因为NameNode在hadoop102上
}catch (Exception e){
System.out.println(e);
}
return fs;
}
public static void main(String[] args) throws IOException, URISyntaxException, InterruptedException {
// 1 获取客户端
FileSystem fs = getConf();
// 2 在hdfs上创建路径
fs.mkdirs(new Path("/school"));
// 3 关闭资源
fs.close();
System.out.println("over");
}
在浏览器中输入http://hadoop102:9000查看根目录下是否有school目录。
注意:
- 在连接前,首先需要配置本机的hosts文件,即主机名和ip的映射关系
- 在连接hadoop102时,相当于使用lg用户登录hadoop102节点,所以需要配置本机和hadoop102之间的SSH免密登录。
HDFS客户端的常用操作
1. 上传文件
// 1 文件上传
@Test
public void testCopyFromLocalFile() throws IOException {
// 1 获取fs对象
FileSystem fs = getConf();
// 2 执行上传API
fs.copyFromLocalFile(new Path(filePath), new Path("/xianzhang.txt"));
// 3 关闭fs对象
fs.close();
}
2. 下载文件
// 2 下载文件
@Test
public void testCopyTOLocalFile() throws IOException {
// 1 获取fs对象
FileSystem fs = getConf();
// 2 执行下载操作
fs.copyToLocalFile(new Path("/school/xianzhang.txt"), new Path(filePath + "/xianzhang.txt"));
// 3 关闭资源
fs.close();
}
3. 删除文件
// 3 文件删除
@Test
public void testDelete() throws IOException {
FileSystem fs = getConf();
fs.delete(new Path("/school"), true);
fs.close();
}
4. 文件更名
// 4 文件更名
@Test
public void testRename() throws IOException {
FileSystem fs = getConf();
fs.rename(new Path("/xianzhang.txt"), new Path("/shizhang.txt"));
fs.close();
}
5. 查看文件详情
// 5 查看文件详情
@Test
public void testListFile() throws IOException {
FileSystem fs = getConf();
// 查看文件详情
RemoteIterator listFiles = fs.listFiles(new Path("/"), true);
while(listFiles.hasNext()) {
LocatedFileStatus fileStatus = listFiles.next();
System.out.println(fileStatus.getPath().getName()); // 文件名
System.out.println(fileStatus.getPermission()); // 权限
System.out.println(fileStatus.getLen()); // 长度
BlockLocation[] blockLocations = fileStatus.getBlockLocations();
for (BlockLocation blockLocation : blockLocations) {
String[] hosts = blockLocation.getHosts();
for (String host : hosts) {
System.out.println(host);
}
}
System.out.println("---------------------------");
}
fs.close();
}
6. 判断文件类型
// 6 判断是文件还是文件夹
@Test
public void testListType() throws IOException {
FileSystem fs = getConf();
// 判断操作
FileStatus[] listStatus = fs.listStatus(new Path("/"));
for (FileStatus fileStatus : listStatus) {
if (fileStatus.isFile()) {
System.out.println("f:" + fileStatus.getPath().getName()); // 文件
} else {
System.out.println("d:" + fileStatus.getPath().getName()); // 目录
}
}
fs.close();
}