HDFS的JAVA API操作

3.5 HDFS的API操作

Hadoop提供了多种HDFS的访问接口,包括C API、HTTP API、REST API以及Java API。这里主要介绍HDFS Java API,API位于"org.apache.hadoop.fs"包中,这些API能够支持的操作包含打开文件、读写文件、删除文件等。

3.5.1 客户端环境准备

  1. 下载Windows依赖文件:hadoop-3.1.0到指定路径。
  2. 配置HADOOP_HOME环境变量

HDFS的JAVA API操作_第1张图片

  1. 配置Path环境变量

HDFS的JAVA API操作_第2张图片

验证Hadoop环境变量是否正常。双击winutils.exe,如果报错误。说明缺少微软运行库,安装微软运行库即可。
HDFS的JAVA API操作_第3张图片

  1. 安装配置Maven,详情见安装Maven博客。
    Maven博客

  2. 在IDEA中创建一个Maven工程HdfsClientDemo,如图:

HDFS的JAVA API操作_第4张图片

  1. 配置POM.xml

将如下配置代码复制到POM.xml文件中:

<dependencies>
  <dependency>
    <groupId>org.apache.hadoopgroupId>
    <artifactId>hadoop-clientartifactId>
    <version>3.1.3version>
  dependency>
  <dependency>
    <groupId>junitgroupId>
    <artifactId>junitartifactId>
    <version>4.12version>
  dependency>
  <dependency>
    <groupId>org.slf4jgroupId>
    <artifactId>slf4j-log4j12artifactId>
    <version>1.7.30version>
  dependency>
dependencies>

结果如图:
HDFS的JAVA API操作_第5张图片

  1. 配置log4j.properties文件

在项目的src/main/resources目录下,新建一个文件,命名为“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

配置完成后如图:
HDFS的JAVA API操作_第6张图片

  1. 创建名为java的文件

创建java文件夹,并将文件夹设置为Sources Root,如图:
HDFS的JAVA API操作_第7张图片

设置完成后才能在java文件夹中创建package,否则不能创建。在java文件夹中创建package:com.li。

  1. 在com.li包中创建HdfsClient类,进行Java API测试,测试代码如下:
package com.li;

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 HdfsClient {

    @Test
    public void testMkdirs() throws IOException, URISyntaxException, InterruptedException {

        // 1 获取文件系统
        Configuration configuration = new Configuration();

        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration,"li");

        // 2 创建目录
        fs.mkdirs(new Path("/school/class01/"));

        // 3 关闭资源
        fs.close();
    }
}

  1. 执行程序

客户端去操作HDFS时,是有一个用户身份的。默认情况下,HDFS客户端API会从采用Windows默认用户访问HDFS,会报权限异常错误。所以在访问HDFS时,一定要配置用户。

org.apache.hadoop.security.AccessControlException: Permission denied: user=56576, access=WRITE, inode="/school/class01/":atg:supergroup:drwxr-xr-x

3.5.2 HDFS API

Hadoop类库中最终面向用户提供的接口类是FileSystem。该类是个抽象类,只能通过类的get方法得到具体类。该类封装了大部分的文件操作,如mkdir、delete等。
HDFS Java API的一般用法如下:

  1. 实例化Configuraion类

Configuraion类封装了客户端或服务器的配置,Configuraion实例会自动加载HDFS的配置文件core-site.xml,从中获取Hadoop集群的配置信息;

Configuration conf = new Configuration();
  1. 实例化FileSystem类

FileSystem类是客户端访问文件系统的入口,是一个抽象的文件系统类。DistributedFielSystem类是FileSystem类的一个具体实现。实例化FileSystem类并返回默认的文件系统的代码如下:

FileSystem fs = FileSystem.get(uri, conf, "username"); // 其中uri是URI类的实例,username表示用户名(字符串类型)
  1. 设置目标对象的路径

HDFS Java API提供了Path类封装HDFS文件路径。Path类位于org.apache.hadoop.fs包中。设置目标对象路径的代码如下:

Path path = new Path("/test");
  1. 执行文件或目录操作

得到FileSystem实例后,就可以使用该实例提供的方法执行相应的操作,例如:打开文件、创建文件、重名命文件、删除文件等。常用方法如下表:

方法名称及参数 返回值 功能
create(Path f) FSDataOutputSteam 创建一个文件
open(Path f) FSDataInputStream 打开指定的文件
delete(Path f) boolean 删除指定文件
exists(Path f) boolean 检查文件是否存在
getBlockSize(Path f) long 返回指定文件的数据块的大小
getLength(Path f) long 返回文件长度
mkdirs(Path f) boolean 建立子目录
copyFromLoalFile(Path src, Path dst) void 从本地磁盘上传文件到HDFS
copyToLoalFile(Path src, Path dst) void 从HDFS下载文件到本地磁盘

3.5.3 操作实例

  1. HDFS文件上传(测试参数优先级)
@Test
public void testCopyFromLocalFile() throws IOException, InterruptedException, URISyntaxException {

    // 1 获取文件系统
    Configuration configuration = new Configuration();
    configuration.set("dfs.replication", "2");
    FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration, "li");

    // 2 上传文件
    fs.copyFromLocalFile(new Path("d:/class01_name.txt"), new Path("/school/class01"));

    // 3 关闭资源
    fs.close();

参数优先级
参数优先级排序:(1)客户端代码中设置的值 >(2)ClassPath下的用户自定义配置文件 >(3)然后是服务器的自定义配置(xxx-site.xml) >(4)服务器的默认配置(xxx-default.xml)

2.HDFS文件下载

@Test
    public void testCopyToLocalFile() throws IOException, InterruptedException, URISyntaxException{

        // 1 获取文件系统
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration, "li");

        // 2 执行下载操作
        // boolean delSrc 指是否将原文件删除
        // Path src 指要下载的文件路径
        // Path dst 指将文件下载到的路径
        // boolean useRawLocalFileSystem 是否开启文件校验
        fs.copyToLocalFile(false, new Path("/school/class01/class01_name.txt"), new Path("d:/class01_name.txt"), true);

        // 3 关闭资源
        fs.close();
    }

  1. HDFS文件更名和移动
@Test
public void testRename() throws IOException, InterruptedException, URISyntaxException{

	// 1 获取文件系统
	Configuration configuration = new Configuration();
	FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration, "li"); 
		
	// 2 修改文件名称
	fs.rename(new Path("/school/class01/class01_name.txt"), new Path("/school/class01/new_class01_name.txt"));
		
	// 3 关闭资源
	fs.close();
}

  1. HDFS删除文件和目录
@Test
public void testDelete() throws IOException, InterruptedException, URISyntaxException{

	// 1 获取文件系统
	Configuration configuration = new Configuration();
	FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration, "li");
		
	// 2 执行删除
	fs.delete(new Path("/school"), true);
		
	// 3 关闭资源
	fs.close();
}

  1. HDFS文件详情查看
@Test
public void testListFiles() throws IOException, InterruptedException, URISyntaxException {

	// 1获取文件系统
	Configuration configuration = new Configuration();
	FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration, "li");

	// 2 获取文件详情
	RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);

	while (listFiles.hasNext()) {
		LocatedFileStatus fileStatus = listFiles.next();

		System.out.println("========" + fileStatus.getPath() + "=========");
		System.out.println(fileStatus.getPermission());
		System.out.println(fileStatus.getOwner());
		System.out.println(fileStatus.getGroup());
		System.out.println(fileStatus.getLen());
		System.out.println(fileStatus.getModificationTime());
		System.out.println(fileStatus.getReplication());
		System.out.println(fileStatus.getBlockSize());
		System.out.println(fileStatus.getPath().getName());

		// 获取块信息
		BlockLocation[] blockLocations = fileStatus.getBlockLocations();
		System.out.println(Arrays.toString(blockLocations));
	}
	// 3 关闭资源
	fs.close();
}

  1. HDFS文件和文件夹判断
@Test
public void testListStatus() throws IOException, InterruptedException, URISyntaxException{

    // 1 获取文件配置信息
    Configuration configuration = new Configuration();
    FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration, "li");

    // 2 判断是文件还是文件夹
    FileStatus[] listStatus = fs.listStatus(new Path("/"));

    for (FileStatus fileStatus : listStatus) {

        // 如果是文件
        if (fileStatus.isFile()) {
            System.out.println("f:"+fileStatus.getPath().getName());
        }else {
            System.out.println("d:"+fileStatus.getPath().getName());
        }
    }

    // 3 关闭资源
    fs.close();
}

你可能感兴趣的:(Hadoop大数据技术,java,hdfs,hadoop)