通过Java API来访问HDFS
1.Windows上配置环境变量
解压Hadoop,然后把Hadoop的根目录配置到HADOOP_HOME环境变量里面
然后把HADOOP_HOME/lib和HADOOP_HOME/bin配置到path里面
2.替换bin目录
将官网下载的Hadoop目录下面的bin目录替换成Windows下编译的Hadoop的bin目录:
我已经上传了自己编译好的hadoop-2.6.1的bin目录,可以从https://pan.baidu.com/s/1P50N60Qb16zuZxSwPq6HaA下载
也可参考他人博客http://blog.csdn.net/mrbcy/article/details/55806809 自已编译适合自己电脑系统的版本即可
3.Eclipse需要的jar包依赖
需要添加的jar包列表如下:
- hadoop/share/hadoop/common/hadoop-common-2.6.4.jar
- hadoop/share/hadoop/common/lib/*.jar
- hadoop/share/hadoop/hdfs/hadoop-hdfs-2.6.4.jar
- hadoop/share/hadoop/hdfs/lib/*.jar
4.使用客户端操作HDFS文件系统
4.1.上传文件(有HADOOP_HOME就可以上传)
package cn.bigdata.hdfs; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.junit.Before; import org.junit.Test; /** * 客户端去操作HDFS时,是有一个用户身份的 * 默认情况下,hdfs客户端api会从jvm中获取一个参数来作为自己的用户身份:-DHADOOP_USER_NAME=root * 也可以在构造客户端fs对象时,通过参数传递进去 */ public class HdfsCientDemo { private FileSystem fs = null; Configuration conf = null; @Before public void inin() throws IOException, InterruptedException, URISyntaxException{ Configuration conf = new Configuration(); //拿到一个文件系统操作的客户端实例对象,最后一个参数为用户名,nameNode访问路径:hdfs://shizhan2:9000 fs = FileSystem.get(new URI("hdfs://shizhan2:9000"),conf,"root"); } //上传文件 @Test public void testUpload() throws Exception{ fs.copyFromLocalFile(new Path("c:/regist.log"), new Path("/regist-copy.log")); fs.close(); } }
运行后,上传文件成功:
4.2.下载文件(替换了bin才可以下载)
@Test public void testDownload() throws Exception { fs.copyToLocalFile(false, new Path("/regist-copy.log"), new Path("D:/"), false); fs.close(); }
4.3.查看conf参数信息:
//查看conf的配置信息 @Test public void testConf(){ Iterator<Entry<String, String>> it = conf.iterator(); while(it.hasNext()){ Entry<String, String> ent = it.next(); System.out.println(ent.getKey() + " : " + ent.getValue()); } }
4.4.创建文件夹:
@Test public void testMkdir() throws Exception { boolean result = fs.mkdirs(new Path("/testmkdir/aaa/bbb")); System.out.println(result); }
4.5.删除文件夹:
@Test public void testDelete() throws Exception { // 递归删除 boolean result = fs.delete(new Path("/testmkdir/aaa/"),true); System.out.println(result); }
4.6.查看目录文件夹信息:
@Test public void testLs() throws Exception { RemoteIterator<LocatedFileStatus> lt = fs.listFiles(new Path("/"), true); while(lt.hasNext()){ LocatedFileStatus fileStatus = lt.next(); System.out.println("name:" + fileStatus.getPath().getName() + " owner:" + fileStatus.getOwner()); } }
5.总结:
在java中操作hdfs,首先要获得一个客户端实例
Configuration conf = new Configuration() FileSystem fs = FileSystem.get(conf) |
而我们的操作目标是HDFS,所以获取到的fs对象应该是DistributedFileSystem的实例;
get方法是从何处判断具体实例化那种客户端类呢?从conf中的一个参数 fs.defaultFS的配置值判断;
如果我们的代码中没有指定fs.defaultFS,并且工程classpath下也没有给定相应的配置,conf中的默认值就来自于hadoop
的jar包中的core-default.xml,默认值为: file:///,则获取的将不是一个DistributedFileSystem的实例,而是一个本地文
件系统的客户端对象