maven依赖:
<dependencies> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>2.7.6</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-hdfs</artifactId> <version>2.7.6</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>compile</scope> </dependency> </dependencies>
为了便于测试这里使用单元测试
Part One
如何获得HDFS文件系统?
可以使用URI/Path配合Configuration来获取。
需要导包如下
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.junit.Test;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
Configuration conf=new Configuration();
URI uri=new URI("hdfs://192.168.183.81:9000");
FileSystem fs = FileSystem.get(uri,conf,"用户名"); // 第三个参数可省
System.out.println(fs);
// 输出结果为:DFS[DFSClient[clientName=DFSClient_NONMAPREDUCE_-1963527693_1, ugi=mycat (auth:SIMPLE)]]
输出结果中,mycat是我的NameNode节点IP映射的主机名,此时获得是HDFS文件系统,如果将上面第三行改为:
FileSystem fs = FileSystem.get(conf);
即不传递uri,则控制台输出的是:
org.apache.hadoop.fs.LocalFileSystem@57a3af25
此时就编程本地文件系统了(默认)。
不过需要注意的是:上面获得HDFS文件系统实例的方式还有其他写法,如:
Configuration conf=new Configuration();
conf.set("fs.defaultFS", "hdfs://192.168.183.81:9000");
FileSystem fs = FileSystem.get(conf);
System.out.println(fs);
输出结果同样是:
DFS[DFSClient[clientName=DFSClient_NONMAPREDUCE_1930027030_1, ugi=mycat (auth:SIMPLE)]]
第一种方式的URI传参和这种conf配置的形式都传递了相同的信息,就是传递了namenode的节点路径信息。但是为什么不设置就输出为本地文件系统呢?很显然在Configuration实例对象conf中存有默认值
。
代码如下:
@Test
public void printConf(){
Configuration config = new Configuration();
for (Map.Entry<String, String> entry : config) {
System.out.println(entry.getKey()+"=>" +entry.getValue());
}
}
输出结果蛮多的,下面仅抽选部分:
...
fs.defaultFS=>file:///
fs.s3a.multipart.size=>104857600
fs.s3a.connection.establish.timeout=>5000
...
不难看出结果显示:fs.defaultFS=>file:///
表示默认使用的是本地文件系统。
Part Two
上面我们仅仅创建一个Configuration对象,但是默认加载了namenode的相关配置,name这些配置在哪里呢?
可以看出,默认配置其实在hadoop-hdfs的jar包hdfs-default里面,其实这个就类似与我们在hadoop的etc/hadoop目录下配置的hdfs-site.xml等文件。
而且经过实验测试,只要我们在项目的src目录下按照hdfs-default.xml形式创建文件名为core-site.xml,core-default.xml的自定义配置文件,按照对应的key来设置默认值就可以实现自动加载。
core-default.xml中:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://192.168.183.81:9000</value>
</property>
</configuration>
java测试代码:
@Test
public void testM() throws IOException, URISyntaxException {
Configuration conf=new Configuration();
FileSystem fs = FileSystem.get(conf);
System.out.println(fs);
}
输出结果:
DFS[DFSClient[clientName=DFSClient_NONMAPREDUCE_-1778937579_1, ugi=mycat (auth:SIMPLE)]]
假如说要使用其他的名称的xml,那么需要使用Configuration对象的addResource方法:
自定义名称的xml
:(user-default.xml
)
文件内容同上面core-default.xml一样。
测试代码:
@Test
public void testCustom() throws IOException {
Configuration conf=new Configuration();
conf.addResource("user-default.xml");
FileSystem fs = FileSystem.get(conf);
System.out.println(fs);
}
结果如下:
DFS[DFSClient[clientName=DFSClient_NONMAPREDUCE_1745930730_1, ugi=mycat (auth:SIMPLE)]]