实验二 HDFS客户端及API操作
实验目的:
1.掌握HDFS的客户端操作,包括上传文件、下载文件、重命名、查看目录等;
2.掌握HDFS的Java API使用,能够利用Java API实现上传、下载等常用操作;
实验内容:
-
HDFS客户端的使用
已搭建好三节点HDFS的前提下,启动集群并在各自节点实现以下操作:
- 在HDFS中创建以自己姓名首字母命名的文件夹(以下以/zs为例)
- 将/etc/mandb.conf从本地拷贝至/zs
- 本地创建test.txt内容为hello hdfs,并从本地剪切到/zs
- 本地创建文件test1.txt,内容为hello Hadoop,并将test1.txt 追加到test.txt文件末尾
- 从HDFS下载test.txt文件到本地
- 查看/zs文件夹下有哪些文件
- 查看test1.txt的文件内容
- 将test1.txt文件拷贝至/input目录
- 删除/input /test1.txt文件
- 通过命令将/zs/test1.txt文件的副本数改为10
- 在DataNode节点找到HDFS数据的存储位置,并将文件/zs/test1.txt本地块删除,观察效果
- 导出fsimage与editslog文件,观察并解释文件内容
将其复制到IDLExml文件中,可以清楚地看到
可见Fsimage中并没有记录块对应的DataNode
这是因为在集群启动之后,要求DataNode上报数据块信息,并且每隔一段时间再次上报
-
利用HDFS的Java API完成以下操作:
下面很重要
(1)在window中配置API环境(下载windows依赖、配置环境变量)并测试
(2)打开IDEA创建Maven工程HDFStest
(3)在pom.xml文件中添加相关依赖(hadoop-client、log4j、junit)
<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>
(4)配置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
junit是单元文件 org.slf4j是日志文件
(5)创建HDFSClient类
(6)编写myMkdirs()函数,实现在HDFS端创建目录JAVA_姓名拼音首字母缩写,并用单元测试进行测试
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.Test;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class zn_mkdir {
@Test
public void myMkdirs() throws URISyntaxException, IOException, InterruptedException {
//获取文件系统
Configuration configuration=new Configuration();
FileSystem fs = FileSystem.get( new URI("hdfs://hadoop101:8020"),configuration,"hadoop");
//创建目录 直接调用它的接口函数 接口函数写好了 用文件系统对象调用它的接口函数
fs.mkdirs(new Path("/JAVA_zn"));
//关闭资源 写入硬盘 输入流 会关闭资源
fs.close();
}
}
(7)编写myUpload()函数,实现将本地文件上传至HDFS,并进行单元测试
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.Test;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class zn_upload {
@Test
public void myUpload() throws IOException, URISyntaxException, InterruptedException {
Configuration configuration= new Configuration();
FileSystem fs= FileSystem.get(new URI("hdfs://hadoop101:8020"),configuration,"hadoop");
fs.copyFromLocalFile(new Path("D://zn_test"),new Path("/JAVA_zn"));
fs.close();
}
}
(8)编写myDownload()函数,将test1.txt文件下载至本地,并进行单元测试
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.Test;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class zn_download {
@Test
public void myDownload() throws IOException, URISyntaxException, InterruptedException {
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop101:8020"), configuration, "hadoop");
fs.copyToLocalFile(false,new Path("/zn/test1.txt"),new Path("D:/test1down.txt"),true);
fs.close();
}
}
(9)编写myRename()函数,实现将test1.txt重命名为 mytest1.txt,并进行单元测试
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.PathHandle;
import org.junit.Test;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class zn_rename {
@Test
public void myRename() throws URISyntaxException, IOException, InterruptedException {
Configuration configuration=new Configuration();
FileSystem fs= FileSystem.get(new URI("hdfs://hadoop101:8020"),configuration,"hadoop");
fs.rename(new Path("/zn/test1.txt"),new Path("/zn/mytest1.txt"));
fs.close();
}
}
文件要指定路径 还有这里文件写错了发现IDEA并不会报错
(10)编写myRm()函数,实现将mytest1.txt删除,并进行单元测试
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.Test;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class zn_rm {
@Test
public void myRm() throws IOException, URISyntaxException, InterruptedException {
Configuration configuration=new Configuration();
FileSystem fs=FileSystem.get(new URI("hdfs://hadoop101:8020"),configuration,"hadoop");
fs.delete(new Path("/zn/mytest1.txt"));
fs.close();
}
}
(11)编写myLs()函数,获取根目录(/)下所有文件的详细信息,包括权限、拥有者、所属组、文件大小、修改时间等。(若存在目录则,递归显示目录中的文件)
package com.nefu.rpc;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.Test;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class zn_ls {
@Test
public void myLs() throws IOException, URISyntaxException, InterruptedException {
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop101:8020"), configuration, "hadoop");
// 调用myLs函数,传入根目录路径
myLs(fs, new Path("/"));
fs.close();
}
// 定义myLs函数,用于获取指定路径下所有文件的详细信息
private void myLs(FileSystem fs, Path path) throws IOException {
FileStatus[] fileStatuses = fs.listStatus(path);
for (FileStatus fileStatus : fileStatuses) {
// 打印文件信息
System.out.println("Path: " + fileStatus.getPath());
System.out.println("Permission: " + fileStatus.getPermission());
System.out.println("Owner: " + fileStatus.getOwner());
System.out.println("Group: " + fileStatus.getGroup());
System.out.println("Size: " + fileStatus.getLen());
System.out.println("Modification Time: " + fileStatus.getModificationTime());
System.out.println("Is Directory: " + fileStatus.isDirectory());
if (fileStatus.isDirectory()) {
// 如果是目录,递归调用myLs函数
myLs(fs, fileStatus.getPath());
}
}
}
}