• 第4章 HDFS操作


    4.1 命令行操作

    可以通过命令行接口与HDFS系统进行交互,这样更加简单直观。下面就介绍一些HDFS系统的常用操作命令。

    1.ls

    使用ls命令可以查看HDFS系统中的目录和文件。例如,查看HDFS文件系统根目录下的目录和文件,命令如下:

    hadooop fs –ls /
    

    递归列出HDFS文件系统根目录下的所有目录和文件,命令如下:

    hadooop fs –ls -R /
    

    2.put

    将本地文件上传到HDFS系统中。例如,将本地文件a.txt上传到HDFS文件系统的/input文件夹中,命令如下:

    hadoop fs –put a.txt /input/
    

    3.moveFromLocal

    将本地文件移动到HDFS文件系统中,可以一次移动多个文件。与put命令类似,不同的是该命令执行后源文件将被删除。例如,将本地文件a.txt移动到HDFS的/input文件夹中,命令如下:

    hadoop fs –moveFromLocal a.txt /input/
    

    4.get

    将HDFS文件系统中的文件下载到本地,注意下载时的文件名不能与本地文件相同,否则会提示文件已经存在。下载多个文件或目录到本地时,要将本地路径设置为文件夹。例如,将HDFS根目录中的input文件夹中的文件a.txt下载到本地,命令如下:

    hadoop fs –get /input/a.txt a.txt
    

    将HDFS根目录中的input文件夹下载到本地,命令如下:

    hadoop fs –get /input/ input
    

    注意:如果用户没有root权限,则本地路径要为用户文件夹下的路径,否则会出现权限问题。

    5.rm

    删除HDFS系统中的文件或文件夹,每次可以删除多个文件或目录。例如,删除HDFS根目录的input文件夹中的文件a.txt,命令如下:

    hadoop fs –rm /input/a.txt
    

    删除HDFS根目录的output文件夹,命令如下:

    hadoop fs -rm -r /output
    

    6.mkdir

    在HDFS系统中创建文件或目录。例如,在HDFS根目录下创建文件夹input,命令如下:

    hadoop fs –mkdir /input/
    

    也可使用-p参数创建多级目录,如果父目录不存在,则会自动创建父目录。命令如下:

    hadoop fs –mkdir –p /input/file
    

    7.cp

    拷贝文件到另一个文件,相当于给文件重命名并保存,但源文件还存在。例如,将/input/a.txt拷贝到/input/b.txt,并保留a.txt,命令如下:

    hadoop fs –cp /input/a.txt /input/b.txt
    

    8.mv

    移动文件到另一个文件,相当于给文件重命名并保存,源文件已不存在。例如,将a.txt移动到b.txt,命令如下:

    hadoop fs –mv /input/a.txt /input/b.txt
    

    4.2 Java API操作

    使用HDFS Java API可以远程对HDFS系统中的文件进行新建、删除、读取等操作。本节主要介绍如何在eclipse中编写HDFS Java API与HDFS文件系统进行交互。

    4.2.1 创建Java工程

    在编写Java API之前,首先需要新建一个Hadoop项目。Hadoop项目的结构与普通的Java项目一样,只是依赖的jar包不同。
    在eclipse中新建一个Maven项目hdfs_demo(Maven项目的搭建此处不做过多讲解),然后在该项目的pom.xml文件中添加以下代码,以引入HDFS的Java API依赖包:

    <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.7.1</version>
        </dependency>
         <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>2.7.1</version>
        </dependency> 
        <dependency>
            <groupId>jdk.tools</groupId>
            <artifactId>jdk.tools</artifactId>
            <version>1.7</version>
            <scope>system</scope>
            <systemPath>${JAVA_HOME}/lib/tools.jar</systemPath>
    </dependency>
    

    配置好pom.xml后,即可进行HDFS Java API的编写。

    4.2.2 读取数据

    FileSystem是HDFS Java API的核心工具类,使用FileSystem API可以很轻松的操作HDFS中的文件。例如,在HDFS文件系统的根目录有一个文件file.txt,可以直接使用FileSystem API读取该文件内容。

    1.编写代码

    在新建的hdfs_demo项目中新建Java类FileSystemCat.java,写入查询显示file.txt文件内容的代码,完整代码如下所示:

    import java.io.InputStream;
    import java.net.URI;
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.fs.FileSystem;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.io.IOUtils;
    
    /**查询文件内容并输出**/
    public class FileSystemCat {
    	public static void main(String[] args) throws Exception {
    		//文件在HDFS系统中的路径
    		String uri="hdfs://192.168.170.128:9000/file.txt";
    		Configuration conf=new Configuration();
    		FileSystem fs=FileSystem.get(URI.create(uri), conf);
    		//打开文件输入流
    		InputStream in=fs.open(new Path(uri));
    		//输出文件内容
    		IOUtils.copyBytes(in, System.out, 4096,false);
    		//关闭输入流
    		IOUtils.closeStream(in);
    	}
    }
    

    代码分析:
    运行HDFS程序之前,需要先初始化Configuration类,该类的主要作用是读取HDFS的系统配置信息,也就是安装Hadoop时候的配置文件。例如core-site.xml、hdfs-site.xml和mapred-site.xml等文件里的信息。如下代码:

    Configuration conf=new Configuration();
    

    FileSystem是一个普通的文件系统API,可以使用静态工厂方法取得FileSystem实例。并传入文件在HDFS系统中的路径与Configuration对象参数。代码如下:

    FileSystem fs=FileSystem.get(URI.create(uri), conf);
    

    通过调用FileSystem对象的open方法,取得文件的输入流。如下代码:

    InputStream in=fs.open(new Path(uri));
    

    2.运行代码

    直接在eclipse中右击运行该程序即可,若控制台中能正确输出文件file.txt的内容,说明代码编写正确。

    4.2.3 创建目录

    FileSystem也提供了创建目录的方法,这个方法会按照客户端请求创建未存在的父目录,就像java.io.File的mkdirs()一样。如果目录创建成功,它会返回true。
    下面这个例子,是在HDFS文件系统根目录,创建一个名为mydir的文件夹。

    1.编写代码

    在新建的hdfs_demo项目中新建Java类CreateDir.java,写入的完整代码如下所示:

    import java.io.IOException;
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.fs.FileSystem;
    import org.apache.hadoop.fs.Path;
    /**创建目录mydir**/
    public class CreateDir {
    	 public static void main(String[] args) throws IOException {
        	  Configuration conf = new Configuration();
              conf.set("fs.default.name", "hdfs://192.168.170.128:9000");
              FileSystem hdfs = FileSystem.get(conf);
              //创建目录
              boolean isok = hdfs.mkdirs(new Path("hdfs:/mydir"));
              if(isok){
                  System.out.println("创建目录成功!");
              }else{
                  System.out.println("创建目录失败!");
              }
              hdfs.close();
          }
    }
    

    2.运行代码

    直接在eclipse中右击运行该程序即可,若控制台中能正确输出“创建目录成功!”,说明代码编写正确。

    4.2.4 创建文件

    FileSystem还提供了创建文件的方法create(),通过调用这个函数,可以在HDFS文件系统中的指定路径创建一个文件,并对文件进行写入内容。例如,在HDFS系统根目录创建一个文件newfile2.txt,并写人内容“我是文件内容”,代码如下:

    public static void createFile() throws Exception {
            Configuration conf = new Configuration();
            conf.set("fs.default.name", "hdfs://192.168.170.128:9000");
            FileSystem fs = FileSystem.get(conf);
            //打开一个输出流
            FSDataOutputStream outputStream = fs.create(new Path("hdfs:/newfile2.txt"));
    //写入文件内容
            outputStream.write("我是文件内容".getBytes());
            outputStream.close();
            fs.close();
            System.out.println("文件创建成功!");
        }
    

    4.2.5 删除文件

    通过调用FileSystem提供的deleteOnExit()函数,可以对HDFS文件系统中已经存在的文件进行删除。例如,删除HDFS系统根目录下的文件newfile.txt,代码如下:

    public static void deleteFile() throws Exception{
             Configuration conf = new Configuration();
             conf.set("fs.default.name", "hdfs://192.168.170.128:9000");
             FileSystem fs = FileSystem.get(conf);
             Path path = new Path("hdfs:/newfile.txt");
             //删除文件
             boolean isok = fs.deleteOnExit(path);
             if(isok){
                 System.out.println("删除成功!");
             }else{
                 System.out.println("删除失败!");
             }
             fs.close();
         }
    

    4.2.6 遍历文件和目录

    我们可以通过FileSystem的listStatus()函数,对HDFS文件系统中指定路径下的所有目录和文件进行遍历。例如,递归遍历HDFS系统根目录下的所有文件和目录并输出路径信息,代码如下:

    public class ListStatus {
    	private static FileSystem hdfs;
    	public static void main(String[] args) throws Exception {
            Configuration conf = new Configuration();
            conf.set("fs.default.name", "hdfs://192.168.170.128:9000");
            hdfs = FileSystem.get(conf);
            //遍历HDFS上的文件和目录 
            FileStatus[] fs = hdfs.listStatus(new Path("hdfs:/")); 
            if (fs.length > 0) { 
                for (FileStatus f : fs) { 
                    showDir(f);
                }
            }
    	}
    	 private static void showDir(FileStatus fs) throws Exception {
             Path path = fs.getPath();
             //输出文件或目录的路径
             System.out.println(path);
             //如果是目录,进行递归遍历该目录下的所有子目录或文件
             if (fs.isDirectory()) {
                 FileStatus[] f = hdfs.listStatus(path);
                 if (f.length > 0) {
                     for (FileStatus file : f) {
                         showDir(file);
                     }
                 }
             }
         }
    }
    

    假设HDFS文件系统的根目录有文件夹input、文件newfile.txt,input中有文件test.txt,则上述代码的输出结果为:

    hdfs://192.168.170.128:9000/input
    hdfs://192.168.170.128:9000/input/test.txt
    hdfs://192.168.170.128:9000/newfile.txt
    

    4.2.7 上传本地文件

    FileSystem提供了一个copyFromLocalFile()函数,可以将操作系统本地的文件上传到HDFS文件系统中。例如,将windows系统中D盘的copy_test.txt文件上传到HDFS文件系统的根目录,代码如下:

    public static void copyFromLocalFile() throws Exception{
        	    //1.创建配置器  
             Configuration conf = new Configuration();
             conf.set("fs.default.name", "hdfs://192.168.170.128:9000");
             //2.取得FileSystem文件系统实例
             FileSystem fs = FileSystem.get(conf);  
             //3.创建可供hadoop使用的文件系统路径  
             Path src = new Path("D:/copy_test.txt"); //本地目录/文件  
             Path dst = new Path("hdfs:/");  //目标目录/文件 
             // 4.拷贝上传本地文件(本地文件,目标路径) 至HDFS文件系统中
             fs.copyFromLocalFile(src, dst);  
             System.out.println("文件上传成功!"); 
         }
    

    4.2.8 下载文件到本地

    FileSystem提供了一个copyToLocalFile()函数,可以将HDFS文件系统中的文件下载到操作系统本地。例如,将HDFS文件系统根目录的文件newfile.txt下载到windows系统中D盘根目录,并重命名为new.txt,代码如下:

    public static void copyToLocalFile() throws Exception{
        	    //1.创建配置器  
             Configuration conf = new Configuration();
             conf.set("fs.default.name", "hdfs://192.168.170.128:9000");
             //2.取得FileSystem文件系统实例
             FileSystem fs = FileSystem.get(conf);  
             //3.创建可供hadoop使用的文件系统路径  
             Path src = new Path("hdfs:/newfile2.txt");//目标目录/文件 
             Path dst = new Path("D:/new.txt");  //本地目录/文件  
             //4.从HDFS文件系统中拷贝下载文件(目标路径,本地文件)至本地
             fs.copyToLocalFile(false,src,dst,true);
             System.out.println("文件下载成功!"); 
         }
    

    原创文章,转载请注明出处!!

    更多内容及Java+大数据个人原创视频,可关注公众号观看:

    原创文章,转载请注明出处!!
  • 相关阅读:
    C# 字典、集合、列表的时间复杂度
    .NET 基础知识 GC垃圾回收
    如何使用ASP.NET Core Web API实现短链接服务
    你真的了解:IIS连接数、IIS并发连接数、IIS最大并发工作线程数、应用程序池的队列长度、应用程序池的最大工作进程数 吗?
    elementui eltable表格排序sortable参数解析
    C# 将一个DataTable的结构直接复制到另一个DataTable
    python入门
    【转自蟹壳】写给20几岁的程序员
    知识图的定义
    用Ruby写的离线浏览代理服务器,只有两百多行代码
  • 原文地址:https://www.cnblogs.com/dreamboy/p/9287974.html
Copyright © 2020-2023  润新知