欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

11、HDFS编程案例

程序员文章站 2024-03-22 13:35:16
...

一、Windows环境配置

1、准备好hadoop的完全分布式按照,具体按照步骤这里不再赘述

此处我的版本为hadoop2.7.6版本,环境配置为Hadoop的完全分布式按照,各个节点具体安排如下

1)机器地址映射关系

192.168.8.240 hadoop01
192.168.8.241 hadoop02
192.168.8.242 hadoop03

2)机器节点安排

hadoop01 namenode datanode nodemanager hadoop02
secondarynamenode datanode nodemanager hadoop03
resourcemanager datanode nodemanager

HDFS:分布式文件

hadoop01为namenode,其他都为datanode(包括hadoop01自己)

YARN:分布式计算

hadoop03为resourcemanager管理节点,其他为计算节点nodemanager

3)说明

namenode最好单独出来,减轻元数据负载压力
secondarynamenode最好不要与namenode放置在同一台机器进行冷备份
resourcemanager最好单独出来避免与nodemanager在同一台机器

4)注意

hadoop完全分布式环境启动注意 hdfs的启动和关闭可以在任意节点进行控制: start-dfs.sh或stop-dfs.sh
yarn的启动和关闭必须在主节点上进行控制:start-yarn.sh或stop-yarn.sh
(必须在resourcemanager节点控制)

2、Windows下环境开发配置

1)环境变量配置
解压hadoop压缩包,此处我的版本为hadoop2.7.6版本

E:\hadoop\hadoop-2.7.6

配置windows环境变量,“我的电脑”-》属性-》高级配置-》环境变量配置,添加系统环境变量

HADOOP_HOME=E:\hadoop\hadoop-2.7.6

修改系统变量Path,其后追加(冒号分隔)

Path=。。。;%HADOOP_HOME%\bin

2)hadoop之windows插件配置
将《windows下hadoop-2.7.4的hadoop.dll以及winutils.rar》解压获得hadoop.dll以及winutils.exe两个插件
将hadoop.dll插件放在windows的system32之下,winutils拷贝至hadoop的安装目录的bin目录下

拷贝hadoop.dll至 C:\Windows\System32 拷贝winutils.exe至
E:\hadoop\hadoop-2.7.6\bin

3)Eclipse插件配置
拷贝Eclipse的hadoop连接插件到eclipse的安装目录

拷贝hadoop-eclipse-plugin-2.7.5.jar至E:\WorkSpace\eclipse\plugins目录
Eclipse安装目录根据自己实际位置进行配置

打开Eclipse,Window-》preferences-》搜索hadoop Map/Reduce,添加hadoop的安装目录

E:\hadoop\hadoop-2.7.6
11、HDFS编程案例
配置Linux中实际的开发环境,包括MapReduce以及YARN地址配置,方式:Window-》show View-》Other然后搜索:
Map/Reduce Localtions
11、HDFS编程案例

在弹出的视图中右键鼠标,点击“New Location”
11、HDFS编程案例
11、HDFS编程案例
然后在弹出的窗口中配置:

Location name: 随意配置一个具有含义的连接名称 Map/Reduce(V2)Master:
此处配置Yarn暴露的地址(见yarn-site.xml配置)和端口9001 DFS
Master:此处配置namenode的主机地址以及端口9000

注意:这里如果配置的host如果为域名,那么必须在WIndows的hosts文件中进行域名映射

打开Project explorer视图,可看到DFS Locations多出了一个hadoop配置,这就是我们刚刚配置的Location name。
11、HDFS编程案例
在这里我们可以通过刷新改位置信息,实时看到我们通过API或者通过linux上传的文件信息。刷新eclipse查看上传的文件
11、HDFS编程案例
查看文件
11、HDFS编程案例

二、Hadoop依赖库配置

1、项目jar的构建

1)新建Java项目Hadoop-DFS01
2)新建main函数入口类

```java
/**  
* @文件名: Driver.java
* @功    能: TODO(用一句话描述该文件做什么)
* @作    者: aaa@qq.com
* @日    期: 2019年12月18日
* @版    本: V1.0  
*/
public class Driver {
     public static void main(String[] args) {
          
     }
}

3)选择项目树-》属性-》Build Path-》Configure Build Path… -》Libraries-》Add Library-》User Library
11、HDFS编程案例

11、HDFS编程案例
选择并新建用户库(第一次没有创建用户库的情况下)
11、HDFS编程案例
我们创建4个库,包括Hadoop的四个核心组件:

Common:通信协议和工具类,所有类型的开发都需要用到RPC协议以及工具库
HDFS:分布式文件系统库,涉及到文件系统的程序都需要
MapReduce:分布式计算程序相关库,一般的MapReduce程序开发核心库
YARN:分布式计算资源调度库

我们先创建4个库,但是这里我们只需要使用Common和HDFS即可,因为我们这里只做HDFS程序开发。其他库是为MapReduce程序开发做准备而准备的库
11、HDFS编程案例
11、HDFS编程案例
选择安装版本的hadoop2.7.6/share/hadoop/common外部的几个jar包和hadoop2.7.6/share/hadoop/common/lib下的所有jar包
11、HDFS编程案例
11、HDFS编程案例
11、HDFS编程案例
新建HDFS库目录,添加E:\hadoop\hadoop-2.7.6\share\hadoop\hdfs下的jar包以及E:\hadoop\hadoop-2.7.6\share\hadoop\hdfs\lib下所有jar包
11、HDFS编程案例
11、HDFS编程案例
新建MapReduce库,选择E:\hadoop\hadoop-2.7.6\share\hadoop\mapreduce下的jar包以及E:\hadoop\hadoop-2.7.6\share\hadoop\mapreduce\lib下所有jar包
11、HDFS编程案例
新建yarn库,选择E:\hadoop\hadoop-2.7.6\share\hadoop\yarn目录下jar以及E:\hadoop\hadoop-2.7.6\share\hadoop\yarn\lib下所有jar包
11、HDFS编程案例
11、HDFS编程案例
最后,所有的库建立完成如下:
11、HDFS编程案例
点击完成,选择common和hdfs库即可(正如我刚说的,我们这里只开发hdfs程序只需要common公共库以及hdfs库即可)

三、HDFS程序开发

这里我们主要讲解的使用hadoop的原生jar包开发,如果使用maven就更简单,所以这里不再对maven配置进行说明

1、项目开发说明
关于HDFS最核心的文件操作类就是FileSystem接口类,通过它你可以操作本地文件系统或者HDFS,如果为空构造函数则操作的就是本地文件系统,文件得根目录就是你程序所在的磁盘的根目录,如果构造函数包括了一个Configure的类则为HDFS文件的操作。

1)、FileSystem与Configuration的分析

/**
   * Returns the configured filesystem implementation.
   * @param conf the configuration to use
   */
  public static FileSystem get(Configuration conf) throws  IOException {
    return get(getDefaultUri(conf), conf);
  }

如果使用的以上的接口获取的位本地文件系统接口,API操作的时候是以程序所在目录的根目录为HDFS的“/”目录,如程序在D盘,上传到根目录为D:/,如果是linux系统配置的单机版,则使用的hadoop的本地文件系统

另一个带参数的的单例构造方法

public static FileSystem get(URI uri, Configuration conf) throws  IOException {
    String scheme = uri.getScheme();
    String authority = uri.getAuthority();
    if (scheme == null && authority == null) {     // use  default FS
      return get(conf);
    }
    if (scheme != null && authority == null) {     // no  authority
      URI defaultUri = getDefaultUri(conf);
      if (scheme.equals(defaultUri.getScheme())    // if scheme  matches default
          && defaultUri.getAuthority() != null) {  // & default  has authority
        return get(defaultUri, conf);              // return  default
      }
    }
    
    String disableCacheName =  String.format("fs.%s.impl.disable.cache", scheme);
    if (conf.getBoolean(disableCacheName, false)) {
      return createFileSystem(uri, conf);
    }
    return CACHE.get(uri, conf);
  }

该接口第一个参数就是HDFS暴露的接口地址,如:hfds://hadoop01:9000,这个接口说明是连接到真实HDFS的接口,上传的文件和下载文件是一个HDFS的根为基础

第三个带参数的单例构造方法

public static FileSystem get(final URI uri, final Configuration  conf,
        final String user) throws IOException,  InterruptedException {
    String ticketCachePath =
       conf.get(CommonConfigurationKeys.KERBEROS_TICKET_CACHE_PATH);
    UserGroupInformation ugi =
        UserGroupInformation.getBestUGI(ticketCachePath, user);
    return ugi.doAs(new PrivilegedExceptionAction<FileSystem>()  {
      @Override
      public FileSystem run() throws IOException {
        return get(uri, conf);
      }
    });
  }

该参数多个一个user,说明连接真实的HDFS时候使用的用户名为hadoop,测试环境下如果在windows上调试如果没有该参数,也没有通过jvm参数设置HADOOP_USER_NAME参数值,那么默认使用的用户为windows用户名(比如登录windows的用户名Administrator),测试时候会报权限错误;如果没有传递user参数而且将开发的代码打包提交到linux下,然后运行,那么则使用的当前linux的用户名(不会像windows一样报错,但是要保证linux的用户是hadoop的用户且有读写权限)

2)默认的配置加载顺序
在hadoop安装的时候,我们环境中使用的配置是:hadoop安装目录/etc/hadoop/hdfs-site.xml, 这里面配置的是hadoop通过脚本上传的默认参数,如包括副本数,那么在开发环境中,我们使用什么配置文件控制hdfs相关参数呢?首先在导入的hadoop的hdfs的jar包中可以看到如下配置文件:
11、HDFS编程案例
11、HDFS编程案例
也就是说,开发的程序jar包中Configuration类首先会从依赖的hadoop-hdfs-2.7.6.jar包中的hdfs-default.xml中加载相关配置,同时我们可以拷贝一份hdfs-default.xml到我们的应用程序目录,然后修改对应参数(比如replication的副本数测试)

<property>
  <name>dfs.replication</name>
  <value>3</value>
  <description>Default block replication.
  The actual number of replications can be specified when the  file is created.
  The default is used if replication is not specified in create  time.
  </description>
</property>

可以发现Configuration的配置加载类顺序为: 依赖的hadoop-hdfs-2.7.6.jar 》本应用程序目录的hdfs-default.xml 也就是说应用程序的配置生效,当然也可把应用程序目录的hdfs-default.xml改为hdfs-site.xml,Configuration会先加载依赖包的hdfs-default.xml,然后到应用程序目录下找hdfs-default.xml或hdfs-site.xml的配置文件是否存在,存在则读取配置并覆盖依赖包中加载的配置,否则如果程序中通过Configuration的set接口配置的参数会覆盖依赖库hadoop-hdfs-2.7.6.jar中的默认配置或应用程序中的hdfs-default.xml的配置,所以总结开发程序中的参数优先级(非加载顺序)如下:

A、通过Configuration的set参数配置对应的参数优先级最高
B、通过应用程序目录下的hdfs-site.xml或hdfs-default.xml配置文件的应用程序参数优先级其次
C、依赖包中的hadoop-hdfs-2.7.6.jar包中的默认的配置文件hdfs-default.xml指定的参数最低

2、eclipse开发环境默认用户配置

首先,我们先测试一个文件文件上传,我们在D盘下创建一个文件D:/测试文件.txt,文件内容如下:11、HDFS编程案例
接下来,我们使用不指定用户名且在开发环境(windows下)中直接使用run as的方式运行hadoop程序的方式进行如下代码的测试,那么会发生什么事情呢?

package com.easystudy;
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;
/**  
* @文件名: Driver.java
* @功     能: TODO(用一句话描述该文件做什么)
* @作     者: aaa@qq.com
* @日     期: 2019年12月18日
* @版     本: V1.0  
*/
public class Driver {
     public static void main(String[] args) throws IOException,  URISyntaxException {
           // 使用默认配置创建hdfs文件系统
           Configuration conf = new Configuration();
           FileSystem fs = FileSystem.get(new  URI("hdfs://hadoop01:9000"), conf);
           
           // 将文件上传至根目录
           fs.copyFromLocalFile(new Path("D:\\测试文件.txt"), new  Path("/"));
           // 关闭文件系统
           fs.close();
     }
}

发生错误如下:

Exception in thread “main”
org.apache.hadoop.security.AccessControlException: Permission denied:
user=Administrator, access=WRITE,
inode="/":hadoop:supergroup:drwxr-xr-x
at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.check(FSPermissionChecker.java:308)
at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.checkPermission(FSPermissionChecker.java:214)
at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.checkPermission(FSPermissionChecker.java:190)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.checkPermission(FSDirectory.java:1752)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.checkPermission(FSDirectory.java:1736)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.checkAncestorAccess(FSDirectory.java:1719)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.startFileInternal(FSNamesystem.java:2541)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.startFileInt(FSNamesystem.java:2476)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.startFile(FSNamesystem.java:2360)
at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.create(NameNodeRpcServer.java:624)
at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.create(ClientNamenodeProtocolServerSideTranslatorPB.java:398)
at org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$ClientNamenodeProtocol2.callBlockingMethod(ClientNamenodeProtocolProtos.java)atorg.apache.hadoop.ipc.ProtobufRpcEngine2.callBlockingMethod(ClientNamenodeProtocolProtos.java) at org.apache.hadoop.ipc.ProtobufRpcEngineServerProtoBufRpcInvoker.call(ProtobufRpcEngine.java:616)atorg.apache.hadoop.ipc.RPCProtoBufRpcInvoker.call(ProtobufRpcEngine.java:616) at org.apache.hadoop.ipc.RPCServer.call(RPC.java:982)
at org.apache.hadoop.ipc.Server$Handler1.run(Server.java:2217)atorg.apache.hadoop.ipc.Server1.run(Server.java:2217) at org.apache.hadoop.ipc.ServerHandler1.run(Server.java:2213)atjava.security.AccessController.doPrivileged(NativeMethod)atjavax.security.auth.Subject.doAs(Subject.java:422)atorg.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1758)atorg.apache.hadoop.ipc.Server1.run(Server.java:2213) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:422) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1758) at org.apache.hadoop.ipc.ServerHandler.run(Server.java:2213)

原因:

这个错误就是开发环境用户配置文件,我们有如下3中方式配置JVM的hadoop使用的用户HADOOP_USER_NAME(注意:这是是jvm参数不是应用程序使用的参数)

解决方法
(1)使用eclipse的运行参数指定jvm参数
11、HDFS编程案例

-DHADOOP_USER_NAME=hadoop

参数-D表示jvm参数指定,后面跟key=value形式的键值对形式,参数名为HADOOP_USER_NAME,参数值为hadoop(我创建的linux的hadoop账户名就是hadoop),然后再次运行即可,刷新左侧树上的节点查看根目录文件是否上传成功
11、HDFS编程案例
因为上传的是中文,看上去是乱码,这里我们先忽略只关注上传成功结果即可!使用web查看文件系统也可以看到上传成功:utilities-》Browser the file system然后输入根目录“/”
11、HDFS编程案例
(2)使用Java的系统类指定jvm参数
修改代码如下:

package com.easystudy;
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;
/**  
* @文件名: Driver.java
* @功     能: TODO(用一句话描述该文件做什么)
* @作     者: aaa@qq.com
* @日     期: 2019年12月18日
* @版     本: V1.0  
*/
public class Driver {
     public static void main(String[] args) throws IOException,  URISyntaxException {
           // 使用jvm系统类指定hadoop运行的用户名
           System.setProperty("HADOOP_USER_NAME", "hadoop");
           
           // 使用默认配置创建hdfs文件系统
           Configuration conf = new Configuration();
           FileSystem fs = FileSystem.get(new  URI("hdfs://hadoop01:9000"), conf);
           
           // 将文件上传至根目录
           fs.copyFromLocalFile(new Path("D:\\测试文件.txt"), new  Path("/测试文件2.txt"));
           // 关闭文件系统
           fs.close();
     }
}

可以看到多了一行系统环境变量设置

// 使用jvm系统类指定hadoop运行的用户名
System.setProperty("HADOOP_USER_NAME", "hadoop");

运行结果如下所示
11、HDFS编程案例
上传后,可以看到多了一个文件“测试文件2.txt”
11、HDFS编程案例
以上的URI配置可以直接通过Configuration进行配置

/**  
* @文件名: Driver.java
* @功     能: TODO(用一句话描述该文件做什么)
* @作     者: aaa@qq.com
* @日     期: 2019年12月18日
* @版     本: V1.0  
*/
public class Driver {
     public static void main(String[] args) throws IOException,  URISyntaxException {
           System.setProperty("HADOOP_USER_NAME", "hadoop");
           
           // 使用默认配置创建hdfs文件系统
           Configuration conf = new Configuration();
           conf.set("fs.defaultFS", "hdfs://hadoop01:9000");
           FileSystem fs = FileSystem.get(conf);
           
           // 将文件上传至根目录
           fs.copyFromLocalFile(new Path("D:\\测试文件.txt"), new  Path("/测试文件3.txt"));
           // 关闭文件系统
           fs.close();
     }
}

(3)程序中直接指定用户名
修改程序如下所示

package com.easystudy;
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;
/**  
* @文件名: Driver.java
* @功     能: TODO(用一句话描述该文件做什么)
* @作     者: aaa@qq.com
* @日     期: 2019年12月18日
* @版     本: V1.0  
*/
public class Driver {
     public static void main(String[] args) throws IOException,  URISyntaxException, InterruptedException {
           // 使用默认配置创建hdfs文件系统
           Configuration conf = new Configuration();
           FileSystem fs = FileSystem.get(new  URI("hdfs://hadoop01:9000"), conf, "hadoop");
           
           // 将文件上传至根目录
           fs.copyFromLocalFile(new Path("D:\\测试文件.txt"), new  Path("/测试文件4.txt"));
           // 关闭文件系统
           fs.close();
     }
}

可以看到,我们通过最后一个参数user直接指定hadoop使用用户为hadoop,二不用去设置JVM的环境变量!刷新结果如下
11、HDFS编程案例
3、文件操作单例类

package com.easystudy.util;


import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;


import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;


/**  
* @文件名: HDFSUtil.java
* @功     能: TODO(HDFS操作工具类)
* @作     者: aaa@qq.com
* @日     期: 2019年12月18日
* @版     本: V1.0  
*/
public class HdfsUtil {
    private String uri = "";
    private String user = "";
    private FileSystem fileSystem = null;
    private static HdfsUtil instance;
    
    private HdfsUtil(String uri, String user){
        this.uri = uri;
        this.user = user;
    }
    
    /**
     * @功    能: TODO(获取文件操作工具实例)
     * @作    者: aaa@qq.com
     * @日    期: 2019年12月18日
     * @说    明:
     * @历    史:aaa@qq.com 1.0
     */
    public synchronized static HdfsUtil getInstance(String uri, String user){
        if(null == instance){
            instance = new HdfsUtil(uri, user);    
        }
        if(null != instance){
            if(!instance.open()){
                instance = null;
            }
        }
        return instance;
    }
    
    /**
     * @功    能: TODO(连接HDFS文件系统)
     * @作    者: aaa@qq.com
     * @日    期: 2019年12月18日
     * @说    明:
     * @历    史:aaa@qq.com 1.0
     */
    private boolean open(){
        Configuration conf = new Configuration();
        //conf.set("fs.defaultFS", uri);
        try {
            fileSystem = FileSystem.get(new URI(uri), conf, user);
            return null != fileSystem;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }        
        return false;
    }
    
    /**
     * @功    能: TODO(关闭连接)
     * @作    者: aaa@qq.com
     * @日    期: 2019年12月18日
     * @说    明:
     * @历    史:aaa@qq.com 1.0
     */
    public void close(){
        if (fileSystem != null) {
            try {
                fileSystem.close();
                fileSystem = null;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

使用方式:

package com.easystudy;
import com.easystudy.util.HdfsUtil;
/**  
* @文件名: Demon.java
* @功     能: TODO(用一句话描述该文件做什么)
* @作     者: aaa@qq.com
* @日     期: 2019年12月18日
* @版     本: V1.0  
*/
public class Demon {
     public static void main(String[] args) {
           // 获取操作实例
           HdfsUtil hdfs =  HdfsUtil.getInstance("hdfs://hadoop01:9000", "hadoop");
           if (hdfs != null) {
                // 文件操作
                // 此处调用封装类的实现方法即可

                // 关闭文件
                hdfs.close();
           }
     }
}

4、创建文件夹

     /**
      * @功    能: TODO(在dfs中级联创建目录)
      * @作    者: aaa@qq.com
      * @日    期: 2019年12月18日
      * @说    明:
      * @历    史:aaa@qq.com 1.0
      */
     public boolean createFolder(String folder){
           if (fileSystem == null) {
                return false;
           }
           try {
                if(!fileSystem.exists(new Path(folder))){
                     return fileSystem.mkdirs(new  Path(folder));
                }
                return true;
           } catch (Exception e) {
                e.printStackTrace();
           }
           return false;
     }

如果文件夹存在则无需创建,不存在则创建,两者情况都返回成功,除非创建失败!

5、上传文件

    /**
      * @功    能: TODO(上传文件到HDFS文件服务器)
      * @作    者: aaa@qq.com
      * @日    期: 2019年12月18日
      * @说    明:
      * @历    史:aaa@qq.com 1.0
      */
     public boolean upload(String src, String dest){
           if (fileSystem == null) {
                return false;
           }
           try {
                fileSystem.copyFromLocalFile(new Path(src), new  Path(dest));
                return true;
           } catch (Exception e) {
                e.printStackTrace();
           }
           return false;
     }

11、HDFS编程案例
6、下载文件

     /**
      * @功    能: TODO(从HDFS下载文件到本地)
      * @作    者: aaa@qq.com
      * @日    期: 2019年12月18日
      * @说    明:
      * @历    史:aaa@qq.com 1.0
      */
     public boolean download(String src, String dest){
           if (fileSystem == null) {
                return false;
           }
           try {
                fileSystem.copyToLocalFile(new Path(src), new  Path(dest));
                return true;
           } catch (Exception e) {
                e.printStackTrace();
           }
           return false;
     }

11、HDFS编程案例
可以看到下载的文件和下载的一个crc文件完整性校验文件(用于与hadoop中存储的块的meta文件进行校验,检查是否损坏)!

7、创建0字节的新文件

     /**
      * @功    能: TODO(一个创建0字节且不存在的文件)
      * @作    者: aaa@qq.com
      * @日    期: 2019年12月18日
      * @说    明:
      * @历    史:aaa@qq.com 1.0
      */
     public boolean createFileIfNotExist(String path){
           if (fileSystem == null) {
                return false;
           }
           try {
                if(fileSystem.exists(new Path(path))){
                     return false;
                }
                return fileSystem.createNewFile(new Path(path));
           } catch (Exception e) {
                e.printStackTrace();
           }
           return false;
     }

创建结果
11、HDFS编程案例
8、删除文件

     /**
      * @功    能: TODO(从HDFS中删除一个存在的文件)
      * @作    者: aaa@qq.com
      * @日    期: 2019年12月18日
      * @说    明:
      * @历    史:aaa@qq.com 1.0
      */
     public boolean deleteFile(String filePath){
           if (fileSystem == null) {
                return false;
           }
           try {
                return fileSystem.delete(new Path(filePath),  false);
           } catch (Exception e) {
                e.printStackTrace();
           }
           return false;
     }

9、删除目录(递归目录,如果目录下有文件则删除文件)

     /**
      * @功    能: TODO(清空目录)
      * @作    者: aaa@qq.com
      * @日    期: 2019年12月18日
      * @说    明:
      * @历    史:aaa@qq.com 1.0
      */
     public boolean deleteDirectory(String dir){
           if (fileSystem == null) {
                return false;
           }
           try {
                FileStatus[] status = fileSystem.listStatus(new  Path(dir));
                if (null == status) {
                     fileSystem.delete(new Path(dir), false);
                } else {
                     for(FileStatus fs : status){
                           if (fs.isFile()) {
                                fileSystem.delete(fs.getPath(),  false);
                           } else {
                                deleteDirectory(fs.toString());
                           }
                     }
                     fileSystem.delete(new Path(dir), true);
                }
                return true;
           } catch (Exception e) {
                e.printStackTrace();
           }
           return false;
     }

10、文件重名名或文件位置移动

     /**
      * @功    能: TODO(将已经存在的文件或文件夹重命名为另一个文件或文件夹)
      * @作    者: aaa@qq.com
      * @日    期: 2019年12月18日
      * @说    明:
      * @历    史:aaa@qq.com 1.0
      */
     public boolean rename(String oldPath, String newPath){
           if (fileSystem == null) {
                return false;
           }
           try {
                if (!fileSystem.exists(new Path(oldPath))) {
                     return false;
                }
                if (fileSystem.exists(new Path(newPath))) {
                     return false;
                }
                return fileSystem.rename(new Path(oldPath), new  Path(newPath));
           } catch (Exception e) {
                e.printStackTrace();
           }
           return false;
     }

11、列举目录下所有文件

     /**
      * @功    能: TODO(列举目录下所有文件)
      * @作    者: aaa@qq.com
      * @日    期: 2019年12月18日
      * @说    明:
      * @历    史:aaa@qq.com 1.0
      */
     public String[] listFiles(String dir){
           List<String> files = new ArrayList<String>();
           if (fileSystem == null) {
                return toArray(files);
           }
           try {
                RemoteIterator<LocatedFileStatus> it =  fileSystem.listFiles(new Path(dir), true);
                if (it != null) {
                     while (it.hasNext()) {
                           LocatedFileStatus st =  (LocatedFileStatus) it.next();
                           if (st != null) {
                                files.add(st.getPath().toString());
                           }
                     }
                }
           } catch (Exception e) {
                e.printStackTrace();
           }
           return toArray(files);
     }
     
     /**
      * @功    能: TODO(列表转数组)
      * @作    者: aaa@qq.com
      * @日    期: 2019年12月18日
      * @说    明:
      * @历    史:aaa@qq.com 1.0
      */
     public String[] toArray(List<String> files){
           String[] arr = new String[files.size()];
           int i = 0;
           for (String st: files) {
                arr[i++] = st;
           }
           return arr;
     }

12、二进制文件读取

/**
      * @功    能: TODO(打开文件获取文件输入流)
      * @作    者: aaa@qq.com
      * @日    期: 2019年12月18日
      * @说    明:
      * @历    史:aaa@qq.com 1.0
      */
     public FSDataInputStream Open(String file){
           if (fileSystem == null) {
                return null;
           }
           try {
                return fileSystem.open(new Path(file));
           } catch (Exception e) {
                e.printStackTrace();
           }
           return null;
     }
     
     /**
      * @功    能: TODO(从打开的文件中读取一行)
      * @作    者: aaa@qq.com
      * @日    期: 2019年12月18日
      * @说    明:
      * @历    史:aaa@qq.com 1.0
      */
     @SuppressWarnings("deprecation")
     public String readLine(FSDataInputStream in){
           try {
                return in.readLine();
           } catch (Exception e) {
                e.printStackTrace();
           }
           return null;
     }
     
     /**
      * @功    能: TODO(关闭文件输入流)
      * @作    者: aaa@qq.com
      * @日    期: 2019年12月18日
      * @说    明:
      * @历    史:aaa@qq.com 1.0
      */
     public void close(FSDataInputStream in){
           try {
                in.close();
           } catch (Exception e) {
                e.printStackTrace();
           }
     }

13、二进制写文件

     /**
      * @功    能: TODO(通过二进制流形式读取文件并上传到HDFS)
      * @作    者: aaa@qq.com
      * @日    期: 2019年12月18日
      * @说    明:
      * @历    史:aaa@qq.com 1.0
      */
     public boolean write(File file, String newFilePath){
           if (fileSystem == null) {
                return false;
           }
           
           FileInputStream in = null;
           FSDataOutputStream out = null;
           try {
                if (fileSystem.exists(new Path(newFilePath))) {
                     return false;
                }
                
                in = new FileInputStream(file);
                out = fileSystem.create(new Path(newFilePath),  false);
                
                byte[] buf = new byte[1024*1024];
                int length = 0;
                while ((length = in.read(buf, 0, 1024*1024)) >  0) {
                     out.write(buf, 0, length);
                }
                return true;
           } catch (Exception e) {
                e.printStackTrace();
           } finally {
                try {
                     if (in != null) {
                           in.close();
                     }
                     if (out != null) {
                           out.close();
                     }
                } catch (Exception e2) {
                     e2.printStackTrace();
                }               
           }
           return false;
     }

以上接口的测试用例如下:

package com.easystudy;
import java.io.File;
import com.easystudy.util.HdfsUtil;
/**  
* @文件名: Demon.java
* @功     能: TODO(用一句话描述该文件做什么)
* @作     者: aaa@qq.com
* @日     期: 2019年12月18日
* @版     本: V1.0  
*/
public class Demon {
     public static void main(String[] args) {
           HdfsUtil hdfs =  HdfsUtil.getInstance("hdfs://hadoop01:9000", "hadoop");
           if (hdfs != null) {
                hdfs.createFolder("/001");
                hdfs.createFolder("/001/002/003");
                hdfs.upload("d:\\article.txt", "/001/002");
                hdfs.upload("d:\\article.txt", "/001/002/003");
                //hdfs.download("/001/article.txt",  "D:\\english.txt");
                //hdfs.createFileIfNotExist("/001/001.txt");
                //hdfs.deleteFile("/001/001.txt");
                //hdfs.deleteDirectory("/001");
                //hdfs.rename("/001/002/article.txt",  "/001/article2.txt");
                
//              String[] files = hdfs.listFiles("/001");
//              for (String string : files) {
//                   System.out.println(string);
//              }
                
//              FSDataInputStream in =  hdfs.Open("/001/article2.txt");
//              System.out.println(hdfs.readLine(in));
//              hdfs.close(in);
                
                hdfs.write(new File("d:\\article.txt"),  "/001/1.txt");
                
                hdfs.close();
           }
     }
}
相关标签: 大数据