使用Java API 访问HDFS上的数据

一.概述

  • 除了可以用HDFS shell的方式 来访问HDFS上的数据,Hadoop还提供了以Java API的方式来操作HDFS上的数据.由于我们实际开发的大数据应用都是以代码的方式提交的,所以在代码中使用API的方式来操作HDFS数据必须掌握

二.搭建环境

1.使用Maven构建Java程序,添加maven的依赖包

  • 在pom.xml文件中的<dependencies>标签下添加如下代码:
<dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-common</artifactId>
      <version>2.6.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-hdfs</artifactId>
      <version>2.6.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-client</artifactId>
      <version>2.6.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-mapreduce-client-core</artifactId>
      <version>2.6.0</version>
    </dependency>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.2</version>
    </dependency>

2.修改hdfs-site.ml文件,添加如下配置,放开权限,重启hdfs服务

<!-- 设置权限关闭,易于访问操作,否则可能因权限问题无法访问 -->
<property>
  <name>dfs.permissions</name>
  <value>false</value>
</property>

3.单元测试的setUp和tearDown方法

  • 在单元测试中,一般将初始化的操作放在setUp方法中完成,将关闭资源的操作放在tearDown方法中完成,代码如下:
package hadoop.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.net.URI;

/**
 * @author sunyong
 * @date 2020/06/30
 * @description
 */
public class HDFSApp {
    public static final String HDFS_PATH="hdfs://hadoop110:9000";
    Configuration cfg=null;
    FileSystem fs = null;

    @Before
    public void setUp() throws Exception{
        System.out.println("HDFSApp.setUp()");
        cfg = new Configuration();
        fs= FileSystem.get(new URI(HDFS_PATH),cfg);
    }
    @After
    public void tearDown() throws Exception{
        cfg = null;
        fs= null;
        System.out.println("HDFSApp.tearDown()");
    }

}

4.使用Java API操作HDFS的常用操作

1)创建目录

 //创建目录操作
    @Test
    public void mkdir()throws Exception{
        String path = "/hdfsapi/test";
        fs.mkdirs(new Path(path));
        System.out.println("目录创建成功");
    }
  • 执行效果如如下:
    在这里插入图片描述
  • 去50070端口查看是否创建成功:
    在这里插入图片描述
  • 如上图所示创建成功!

2)创建文件并写入数据

 //创建文件操作
    @Test
    public void createFile()throws Exception{
        String path = "/hdfsapi/test/a.txt";
        FSDataOutputStream fsdos = fs.create(new Path(path));
        fsdos.write("hello world,I am creating file and output data".getBytes());
        fsdos.flush();
        System.out.println("创建文件并写入数据成功!");
        fsdos.close();
    }
  • 执行效果如下:
    在这里插入图片描述
  • 去hadoop环境下查看有没有该文件: hdfs dfs -cat /hdfsapi/test/a.txt,执行效果如下可知已创建文件并写入数据成功
    在这里插入图片描述

3)重命名操作

//重命名
    @Test
    public void rename() throws Exception{
        Path oldPath = new Path("/hdfsapi/test/a.txt");
        Path newPath = new Path("/hdfsapi/test/b.txt");
        System.out.println(fs.rename(oldPath,newPath));
    }
  • 执行效果如下:
    在这里插入图片描述
  • 去50070端口查看是否改名了,如下已成功改名:
    在这里插入图片描述

4)上传本地文件到HDFS

 //上传本地文件(是Java环境所在系统的文件,我这里是windows系统所以直接用的工程目录下的文件)到hdfs
    @Test
    public void copyFromLocal() throws Exception{
        //要复制的文件
        Path src = new Path("copyFile");
        //目标目录
        Path dist = new Path("/hdfsapi/test/");
        fs.copyFromLocalFile(src,dist);
        System.out.println("上传成功");
    }
  • 执行效果如下:
    在这里插入图片描述
  • 去50070端口查看是否成功,如下:
    在这里插入图片描述

5)查看某目录下的所有文件

//查看某目录下所有文件
    @Test
    public void listFiles() throws Exception{
        FileStatus[] listStatus = fs.listStatus(new Path("/hdfsapi/test/"));
        for (FileStatus status : listStatus) {
            //判断是文件还是目录
            String isDir = status.isDirectory()?"文件夹":"文件";
            //权限
            String permission = status.getPermission().toString();
            //副本系数
            short replication = status.getReplication();
            //长度
            long len = status.getLen();
            //路径
            String path = status.getPath().toString();
            System.out.println(isDir+"\t"+permission+"\t"+replication+"\t"+len+"\t"+path);
        }
    }
  • 执行效果如下:
    在这里插入图片描述

6)查看文件块信息

//查看文件块信息,即备份在哪几台机器,由于我布置的hadoop是伪分布环境,只有一台机器
    @Test
    public void getFileBlock() throws Exception{
        FileStatus fileStatus = fs.getFileStatus(new Path("/hdfsapi/test/b.txt"));
        BlockLocation[] blocks=fs.getFileBlockLocations(fileStatus,0,fileStatus.getLen());
        for (BlockLocation block : blocks) {
            for (String host : block.getHosts()) {
                System.out.println(host);
            }
        }
    }
  • 执行结果如下:
    在这里插入图片描述

7)下载一个文件到本地

  • 注意:下载时需要在windows系统上配置hadoop
  • a.解压hadoop压缩文件到windows系统上
    在这里插入图片描述
  • b.在windows系统上配置hadoop的环境变量
    在这里插入图片描述
    在这里插入图片描述
  • d.将以下文件拖入hadoop解压后目录的bin目录下,将hadoop.dll文件拖入系统盘的System32目录下(提取码: azpe)
    点我获取
    在这里插入图片描述
  • c.修改windows系统的主机列表(添加虚拟机上的主机):
    在这里插入图片描述
//下载一个文件到本地
    @Test
    public void testCopyToLocalFile() throws URISyntaxException, IOException, InterruptedException {
        fs.copyToLocalFile(new Path("/user/java/copyFile"),new Path("F:\\sunyong\\Java\\codes\\javaToHdfs\\download\\copyFile2.txt"));
        System.out.println("下载成功!");
    }
  • 执行效果如下
    在这里插入图片描述
  • 查看内容:
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/sun_0128/article/details/107032911