• 利用Java API通过路径过滤上传多文件至HDFS


      在本地文件上传至HDFS过程中,很多情况下一个目录包含很多个文件,而我们需要对这些文件进行筛选,选出符合我们要求的文件,上传至HDFS。这时就需要我们用到文件模式。 在项目开始前,我们先掌握文件模式

    1、文件模式

      在某个单一操作中处理一系列文件是很常见的。例如一个日志处理的MapReduce作业可能要分析一个月的日志量。如果一个文件一个文件或者一个目录一个目录的声明那就太麻烦了,我们可以使用通配符(wild card)来匹配多个文件(这个操作也叫做globbing)。

      Hadoop提供了两种方法来处理文件组:

    1 public FileStatus[] globStatus(Path pathPattern) throws IOException;
    2 
    3 public FileStatus[] globStatus(Path pathPattern, PathFilter filter) throws IOException;
    • PathFilter

      使用文件模式有时候并不能有效的描述你想要的一系列文件,例如如果你想排除某个特定文件就很难。所以FileSystem的listStatus()和globStatus()方法就提供了一个可选参数:PathFilter——它允许你一些更细化的控制匹配:

    1 package org.apache.hadoop.fs;
    2 
    3 public interface PathFilter
    4 {
    5     boolean accept(Path path);
    6 }
    • Hadoop中的匹配符与Unix中bash相同,如下图所示:、

      

      

    2、数据

      我们利用通配符和PathFilter 对象,将本地多种格式的文件上传至 HDFS,并过滤掉txt文本格式以外的文件

      数据我随便造了些,如下

      

    3、分析

      基于需求,我们通过以下两步完成:

      1、首先使用globStatus(Path pathPattern, PathFilter filter),完成文件格式过滤,获取所有 txt 格式的文件。

      2、然后使用 Java API 接口 copyFromLocalFile,将所有 txt 格式的文件上传至 HDFS

    4、实现

      首先定义一个类 RegexAcceptPathFilter实现 PathFilter,过滤掉 txt 文本格式以外的文件。

     1 /** 
     2 * @ProjectName PathFilter
     3 * @PackageName com.buaa
     4 * @ClassName RegexAcceptPathFilter
     5 * @Description 只接受符合regex的文件
     6 * @Author 刘吉超
     7 * @Date 2016-04-15 20:39:21
     8 */
     9 public static class RegexAcceptPathFilter implements PathFilter {
    10     private final String regex;
    11 
    12     public RegexAcceptPathFilter(String regex) {
    13         this.regex = regex;
    14     }
    15 
    16     @Override
    17     public boolean accept(Path path) {
    18         boolean flag = path.toString().matches(regex);
    19         // 只接受符合regex的文件
    20         return flag;
    21     }
    22 }

      如果要接收 regex格式的文件,则accept()方法就return flag; 如果想要过滤掉regex格式的文件,则accept()方法就return !flag。

      接下来在 uploadFile方法中,使用globStatus方法获取所有txt文件,然后通过copyFromLocalFile方法将文件上传至HDFS。

     1 /**
     2  * 过滤文件格式   将多个文件上传至 HDFS
     3  * 
     4  * @param srcPath 源路径
     5  * @param destPath 目标路径
     6  * @param filter 正则
     7  * @throws URISyntaxException
     8  * @throws IOException
     9  */
    10 public static void uploadFile(String srcPath,String destPath,String filter) throws URISyntaxException, IOException {
    11     // 读取配置文件
    12     Configuration conf = new Configuration();
    13     // 远端文件系统
    14     URI uri = new URI(HDFSUri.trim());
    15     FileSystem remote = FileSystem.get(uri,conf);;
    16     // 获得本地文件系统
    17     FileSystem local = FileSystem.getLocal(conf);
    18     
    19     // 只上传srcPath目录下符合filter条件的文件
    20     FileStatus[] localStatus = local.globStatus(new Path(srcPath), new RegexAcceptPathFilter(filter));
    21     // 获得所有文件路径
    22     Path[] listedPaths = FileUtil.stat2Paths(localStatus);
    23        
    24     if(listedPaths != null){
    25         for(Path path : listedPaths){
    26                 // 将本地文件上传到HDFS
    27             remote.copyFromLocalFile(path, new Path(HDFSUri + destPath));
    28         }
    29     }
    30 }

      在 main() 方法在调用 uploadFile,执行多文件上传至 HDFS

    1 public static void main(String[] args) throws IOException,URISyntaxException {
    2     // 第一个参数:代表是源路径
    3     // 第二个参数:代表是目录路径
    4     // 第三个参数:代表是正则,这里我们只有上传txt文件,所以正则是^.*txt$
    5     uploadFile("D:\data\*","/buaa/data","^.*txt$");
    6 }

    如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
    如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
    如果,您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是【刘超★ljc】。

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

    地址:下载

  • 相关阅读:
    python基础学习-无参装饰器
    python基础学习-day16==课后作业练习(函数对象和闭包)
    python基础学习-函数闭包
    python基础学习-函数对象与函数嵌套
    4.15作业
    反射、元类
    Mixins、多态、绑定方法与非绑定方法
    propety装饰器、继承
    封装
    4.8作业
  • 原文地址:https://www.cnblogs.com/codeOfLife/p/5397734.html
Copyright © 2020-2023  润新知