ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

hdfs的Java API操作

2021-08-01 20:31:46  阅读:224  来源: 互联网

标签:hdfs fs Java Path API conf FileSystem new


1 环境准备

将在Windows环境中编译过的hadoop jar包解压缩到非中文路径;

设置环境变量:

 打开IDEA,创建一个Maven工程;

在pom.xml文件中添加如下依赖,点击右上角的Load Maven Changes开始下载依赖;

 1     <dependencies>
 2         <dependency>
 3             <groupId>junit</groupId>
 4             <artifactId>junit</artifactId>
 5             <version>RELEASE</version>
 6         </dependency>
 7         <dependency>
 8             <groupId>org.apache.logging.log4j</groupId>
 9             <artifactId>log4j-core</artifactId>
10             <version>2.8.2</version>
11         </dependency>
12         <dependency>
13             <groupId>org.apache.hadoop</groupId>
14             <artifactId>hadoop-common</artifactId>
15             <version>2.7.2</version>
16         </dependency>
17         <dependency>
18             <groupId>org.apache.hadoop</groupId>
19             <artifactId>hadoop-client</artifactId>
20             <version>2.7.2</version>
21         </dependency>
22         <dependency>
23             <groupId>org.apache.hadoop</groupId>
24             <artifactId>hadoop-hdfs</artifactId>
25             <version>2.7.2</version>
26         </dependency>
27         <dependency>
28             <groupId>jdk.tools</groupId>
29             <artifactId>jdk.tools</artifactId>
30             <version>1.8</version>
31             <scope>system</scope>          
32             <systemPath>${JAVA_HOME}/lib/tools.jar</systemPath>
33         </dependency>
34     </dependencies>

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

 

2 使用FileSystem对象的方法操作hdfs

    @Test
    public void testHdfsJavaAPI() throws URISyntaxException, IOException, InterruptedException {
        // 1 获取FileSystem对象
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.10.102:9000"), conf, "wm");

        // 2 创建文件目录
        fs.mkdirs(new Path("/hdfsPath"));

        // 3 上传文件
        fs.copyFromLocalFile(new Path("D:/localFile.txt"), new Path("/hdfsPath/hdfsFile.txt"));

        // 4 下载文件
        fs.copyToLocalFile(new Path("/hdfsPath/hdfsFile.txt"), new Path("D:/localFile2.txt"));

        //  5 删除文件
        fs.delete(new Path("/hdfsPath"), true);

        // 6 关闭资源
        fs.close();
    }
View Code

客户端与hdfs文件系统的连接,首先需要一个FileSystem对象,它起到“桥梁”的作用。FileSystem类有一个静态的get()方法,用于返回FileSystem对象。get()方法共有3个参数,分别是:hdfs中NameNode地址、Configuration对象、访问的用户名。其中,FileSystem在org.apache.hadoop.fs包下,Configuration在org.apache.hadoop.conf包下,URI在Java.net包下。new URI()会抛出异常URISyntaxException,FileSystem.get()会抛出异常IOException、InterruptedException。

        // 1 获取FileSystem对象
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.10.102:9000"), conf, "wm");

FileSystem对象的mkdirs(hdfsFilePath)方法用于创建hdfs文件目录。其中,Path类在org.apache.hadoop.fs包下。

        // 2 创建文件目录
        fs.mkdirs(new Path("/hdfsPath"));

FileSystem对象的copyFromLocalFile(localFilePath, hdfsFilePath)方法用于从本地上传文件至hdfs系统,copyToLocalFile(hdfsFilePath, localFilePath)方法用于下载文件。

        // 3 上传文件
        fs.copyFromLocalFile(new Path("D:/localFile.txt"), new Path("/hdfsFile.txt"));
        // 4 下载文件
        fs.copyToLocalFile(new Path("/hdfsFile.txt"), new Path("D:/localFile2.txt"));

FileSystem对象的delete(hdfsPath, boolean)方法用于删除hdfs文件目录或文件,第二个参数为true时,表示递归删除。

        //  5 删除文件
        fs.delete(new Path("/hdfsPath"), true);

最后,关闭FileSystem对象资源。

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

 

3 使用流对象操作hdfs

    // 上传文件至hdfs
    @Test
    public void testPutFileToHdfs() throws URISyntaxException, IOException, InterruptedException {
        // 1 获取FileSystem对象
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.10.102:9000"), conf, "wm");

        // 2 获取输入流
        FileInputStream fis = new FileInputStream("D:/localFile.txt");
        // 3 获取输出流
        FSDataOutputStream fos = fs.create(new Path("/hdfsFile.txt"));

        // 4 数据传输
        IOUtils.copyBytes(fis, fos, conf);

        // 5 关闭资源
        IOUtils.closeStream(fos);
        IOUtils.closeStream(fis);
        fs.close();
    }
View Code

首先,获取FileSystem对象。

        // 1 获取FileSystem对象
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.10.102:9000"), conf, "wm");

之后,获取输入流与输出流对象。当从本地上传文件至hdfs时,本地文件是输入流,hdfs文件是输出流;当从hdfs下载文件至本地时,hdfs文件是输入流,本地文件是输出流。下面以上传文件为例。输入流FileInputStream对象通过实例化FileInputStream类得到,构造函数参数为本地文件路径。输出流FSDataOutputStream对象通过FileSystem对象的create(hdfsPath)方法得到。

        // 2 获取输入流
        FileInputStream fis = new FileInputStream("D:/localFile.txt");
        // 3 获取输出流
        FSDataOutputStream fos = fs.create(new Path("/hdfsFile.txt"));

输入流和输出流都获取完毕后,使用IOUtils类的静态方法copyBytes(InputStream,OutputStream,Configuration)进行流之间的数据传输。

        // 4 数据传输
        IOUtils.copyBytes(fis, fos, conf);

最后,关闭资源。

        // 5 关闭资源
        IOUtils.closeStream(fos);
        IOUtils.closeStream(fis);
        fs.close();

从hdfs下载文件至本地类似,只是输入流和输出流的获取有些变化,代码如下。

    // 从hdfs下载文件至本地
    @Test
    public void testGetFileFromHdfs() throws URISyntaxException, IOException, InterruptedException {
        // 1 获取FileSystem对象
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.10.102:9000"), conf, "wm");

        // 2 获取输入流
        FSDataInputStream fis = fs.open(new Path("/hdfsFile.txt"));
        // 3 获取输出流
        FileOutputStream fos = new FileOutputStream("D:/localFile.txt");

        // 4 数据传输
        IOUtils.copyBytes(fis, fos, conf);

        // 5 关闭资源
        IOUtils.closeStream(fos);
        IOUtils.closeStream(fis);
        fs.close();
    }
View Code

如果只是想在客户端查看hdfs文件的内容而不下载至本地,也是可以的,此时输出流可以换成System.out对象。代码如下。

    // 查看hdfs文件内容
    @Test
    public void testCatFile() throws URISyntaxException, IOException, InterruptedException {
        // 1 获取FileSystem对象
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.10.102:9000"), conf, "wm");

        // 2 获取输入流
        FSDataInputStream fis = fs.open(new Path("/hdfsFile.txt"));
        // 3 获取输出流
        OutputStream os = System.out;

        // 4 数据传输
        IOUtils.copyBytes(fis, os, conf);

        // 5 关闭资源
        IOUtils.closeStream(fis);
        IOUtils.closeStream(os);
        fs.close();
    }

参考:

【尚硅谷】大数据Hadoop 2.x教程丨配套实战案例

《Hadoop权威指南 大数据的存储与分析-第4版》

标签:hdfs,fs,Java,Path,API,conf,FileSystem,new
来源: https://www.cnblogs.com/wangmengdx/p/15087554.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有