这篇博客通过客户端代码实现文件上传、文件下载、文件夹删除、文件名更改、文件详情查看、文件和文件夹判断,主要目的是熟悉相关的API。
在进行API操作之前首先得做好客户端操作的相关准备和配置,具体参考HDFS客户端操作前期准备这篇博客。
一切准备就绪之后,就可以打开Eclipse进行代码的实现了。这里都是在HDFSClient类中进行实现的。
1. HDFS文件上传
1.1. 实现代码
@Test
public void testCopyFromLocalFile() throws IOException, InterruptedException, URISyntaxException {
// 1. 获取文件系统
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), conf, "zohar");
// 2. 将本地文件上传至HDFS之中
fs.copyFromLocalFile(new Path("G:/zzh.txt"), new Path("/zzh.txt"));
// 3. 关闭文件系统
fs.close();
}
代码中,通过调用copyFromLocalFile()
方法将本地文件上传到HDFS之中。
运行测试代码,通过浏览器查看,可以看到文件上传成功。
通过上面的图片可以发现这个文件默认的副本数为3,这也是HDFS默认的,那么如果我要修改这个副本数目该如何操作呢?首先想到的应该是通过设置集群的配置文件来改变副本数,这当然是可行的,但是这样一改变,以后所有的文件默认副本数都会变化了(都不是3了),所以这种方法这里暂不考虑,下面通过代码和改变项目配置文件来改变副本数。
1.2. 测试参数优先级
1.2.1. 通过改变项目配置文件来改变
在工程sr/main/resources/
目录下新建hdfs-site.xml
文件,并将下面的内容复制上去(其实这个文件也就是集群里面的配置文件):
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>dfs.replication</name>
<!-- 这里降副本数设置为1 -->
<value>1</value>
</property>
</configuration>
将上传代码中的目标文件名称修改(这里我修改为了zzh1.txt
),然后重新运行测试代码,可以发现副本数为1,如下图所示。
1.2.2. 通过代码改变
具体实现代码如下:
@Test
public void testCopyFromLocalFile() throws IOException, InterruptedException, URISyntaxException {
// 1. 获取文件系统
Configuration conf = new Configuration();
conf.set("dfs.replication", "2"); // 这里降副本数修改成2
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), conf, "zohar");
// 2. 将本地文件上传至HDFS之中
fs.copyFromLocalFile(new Path("G:/zzh.txt"), new Path("/zzh2.txt"));
// 3. 关闭文件系统
fs.close();
}
这里通过配置文件修改副本数,然后也修改了目的文件名,重新运行测试代码,其结果如下图所示。
1.2.3. 参数优先级
通过上面的一系列操作,如上面介绍过的“通过修改项目配置文件”和“代码实现”参数修改,可以知道通过代码实现参数的修改优先级是最高的,可以覆盖掉“通过修改项目配置文件”对参数的修改(如上面介绍的通过修改项目配置文件将副本数设置为1,而通过代码覆盖掉了可以直接设置成2),因此可以知道参数的优先级为:
客户端中设置的值 > 用户自定义配置文件 > 集群服务器中的配置。
2. HDFS文件下载
这里实现将HDFS文件系统中的文件下载的本地客户端中,具体实现代码如下:
@Test
@Test
public void testCopyToLocalFile() throws IOException, InterruptedException, URISyntaxException {
// 1. 获取文件系统
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), conf, "zohar");
// 2. 将文件系统中的文件下载到本地电脑中
fs.copyToLocalFile(new Path("/zzh2.txt"), new Path("G:/zzh2.txt"));
// 3. 关闭文件系统
fs.close();
}
这里将文件系统中的zzh2.txt
文件下载到本地指定位置。
可以看到可以除了指定要下载的文件,还多了一个crc文件检测文件,这个文件是自动产生的,如果不需要这个文件,可以在代码中使用另外一个方法fs.copyToLocalFile(delSrc, src, dst, useRawLocalFileSystem);
。其中第4个参数就是是否开启文件校验的,设置为True也就不会产生crc文件了。
3. HDFS文件删除
这里将文件系统中的文件或者文件夹删除操作,具体代码如下所示:
@Test
public void testDelete() throws IOException, InterruptedException, URISyntaxException {
// 1. 获取文件系统
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), conf, "zohar");
// 2. 删除文件系统中的文件或者文件夹,第二个参数就是当要删除文件夹是就设置为True。
fs.delete(new Path("/zzh"), true);
// 3. 关闭文件系统
fs.close();
}
4. HDFS文件名更改
@Test
public void testRename() throws IOException, InterruptedException, URISyntaxException {
// 1. 获取文件系统
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), conf, "zohar");
// 2. 执行修改文件名操作
fs.rename(new Path("/zzh.txt"), new Path("/zhangzh"));
// 3. 关闭
fs.close();
}
将文件系统中的zzh.txt
文件修改为了zhangzh
。
5. HDFS文件详情查看
@Test
public void testListFile() throws IOException, InterruptedException, URISyntaxException {
// 1. 获取文件系统
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), conf, "zohar");
// 2. 获取文件详情
RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);
while(listFiles.hasNext()) {
LocatedFileStatus status = listFiles.next();
// 输出文件详情
// 输出文件名
System.out.println(status.getPath().getName());
// 获取文件长度
System.out.println(status.getLen());
// 获取文件权限
System.out.println(status.getPermission());
// 获取存储块信息
BlockLocation[] blockLocations = status.getBlockLocations();
for (BlockLocation blockLocation : blockLocations) {
// 获取主机名称
String[] hosts = blockLocation.getHosts();
for (String host : hosts) {
System.out.println(host);
}
}
System.out.println("-------------------------------------");
}
// 3. 关闭资源
fs.close();
}
测试运行可以看到列出的一些块的信息。
6. HDFS文件和文件夹判断
@Test
public void testListStatus() throws IOException, InterruptedException, URISyntaxException {
// 1. 获取文件系统
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), conf, "zohar");
// 2. 判断文件还是文件夹
FileStatus[] listStatus = fs.listStatus(new Path("/"));
for (FileStatus fileStatus : listStatus) {
if (fileStatus.isFile()) {
// 如果是文件
System.out.println("文件:"+ fileStatus.getPath().getName());
}else {
// 如果是文件夹
System.out.println("文件夹:"+fileStatus.getPath().getName());
}
}
// 3. 关闭文件
fs.close();
}