分布式文件系统HDFS Shell命令和API编程

分布式文件系统HDFS Shell命令和API编程

实验实现过程
重要知识点:

  1. Hadoop分布式文件系统(Hadoop Distributed File System,HDFS)是Hadoop核心组件之一,如果已经安装了Hadoop,其中就已经包含了HDFS组件,不需要另外安装。
  2. 利用Shell命令与HDFS进行交互
    Hadoop支持很多Shell命令,其中fs是HDFS最常用的命令,利用fs可以查看HDFS文件系统的目录结构、上传和下载数据、创建文件等。
    注意

命令是以”./bin/hadoop dfs”开头的Shell命令方式,实际上有三种shell命令方式。

1)	hadoop fs
2)	hadoop dfs(已过期)
3)	hdfs dfs(常用)

hadoop fs适用于任何不同的文件系统,比如本地文件系统和HDFS文件系统
hadoop dfs只能适用于HDFS文件系统
hdfs dfs跟hadoop dfs的命令作用一样,也只能适用于HDFS文件系统
3.常用Shell命令解析

hdfs dfs -appendToFile <localsrc> ... <dst> 

可同时上传多个文件到HDFS里面

hdfs dfs -cat URI [URI ...] 

查看文件内容

hdfs dfs -chgrp [-R] GROUP URI [URI ...] 

修改文件所属组

hdfs dfs -chmod [-R] <MODE[,MODE]... | OCTALMODE> URI [URI ...] 

修改文件权限

hdfs dfs -chown [-R] [OWNER][:[GROUP]] URI [URI ]

修改文件所有者,文件所属组,其他用户的读、写、执行权限

hdfs dfs -copyFromLocal <localsrc> URI

复制文件到hdfs

hdfs dfs -copyToLocal [-ignorecrc] [-crc] URI <localdst> 

复制文件到本地

hdfs dfs -count [-q] <paths>

统计文件及文件夹数目

hdfs dfs -cp [-f] URI [URI ...] <dest>

Hadoop HDFS 文件系统间的文件复制

hdfs dfs -du [-s] [-h] URI [URI ...]

统计目录下的文件及大小

hdfs dfs -dus <args> 

汇总目录下的文件总大小

hdfs dfs -get [-ignorecrc] [-crc] <src> <localdst>

下载文件到本地

hdfs dfs -getmerge <src> <localdst> [addnl]

合并下载文件到本地

hdfs dfs -ls <args> 

查看目录

hdfs dfs -ls -R <args>

循环列出目录、子目录及文件信息

hdfs dfs -mkdir [-p] <paths> 

创建空白文件夹

dfs -moveFromLocal <localsrc> <dst> 

剪切文件到hdfs

hdfs dfs -moveToLocal [-crc] <src> <dst>

剪切文件到本地

hdfs dfs -mv URI [URI ...] <dest>

剪切hdfs文件

hdfs dfs -put <localsrc> ... <dst>

上传文件

hdfs dfs -rm [-skipTrash] URI [URI ...] 

删除文件/空白文件夹

hdfs dfs -rm -r [-skipTrash] URI [URI ...]

递归删除 删除文件及文件夹下的所有文件

hdfs dfs -setrep [-R] [-w] <numReplicas> <path>

修改副本数

hdfs dfs -stat URI [URI ...]

显示文件统计信息

hdfs dfs -tail [-f] URI

查看文件尾部信息

hdfs dfs -test -[ezd] URI

对PATH进行如下类型的检查:
-e PATH是否存在,如果PATH存在,返回0,否则返回1
-z 文件是否为空,如果长度为0,返回0,否则返回1
-d 是否为目录,如果PATH为目录,返回0,否则返回1

hdfs dfs -text <src> 

查看文件内容

hdfs dfs -touchz URI [URI ...]
创建长度为0的空文件
实验内容与步骤:

  1. 配置hadoop的环境变量:
    首先,hadoop shell命令在/bigdata/hadoop-3.1.1/bin目录下,编辑/etc/profile配置文件,增加如下内容:
sudo  vi  /etc/profile
export JAVA_HOME=/opt/java/jdk1.8.0_181
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
export HADOOP_HOME=/bigdata/hadoop-3.1.1 

重新读取:
source /etc/profile

  1. 命令查看方式:
    我们可以在终端输入如下命令,查看dfs总共支持了哪些命令:
    hdfs dfs

在终端输入如下命令,可以查看具体某个命令的作用
例如:我们查看put命令如何使用,可以输入如下命令:

在这里插入图片描述

实验内容与步骤:

  1. 利用Hadoop提供的Shell命令完成以下指定功能,并编程实现相同任务:
    注:请首先练习HDFS shell命令的使用,比如创建文件、文件夹、删除文件、文件夹,上传文件,下载文件,追加文件等常用功能,然后课后完成Java的实现。

(1) 提供一个HDFS的目录的路径,对该目录进行创建和删除操作。创建目录时,如果目录文件所在目录不存在则自动创建相应目录;删除目录时,由用户指定当该目录不为空时是否还删除该目录;
Shell命令实现:
• 创建目录

hdfs dfs -mkdir -p /dir1/dir2 

在这里插入图片描述
• 删除目录(如果目录非空则会提示not empty,不执行删除)

hdfs dfs -rmdir /dir1/dir2 

目录为空时:
在这里插入图片描述
• 强制删除目录

hdfs dfs -rm -r /dir1/dir2 

是否创建成功可以通过浏览器查看

Java实现:

import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.*;import java.io.*;public class HdfsApi {
 /**
  * 判断路径是否存在
  */
 public static boolean test(Configuration conf, String path) throws IOException {
     FileSystem fs = FileSystem.get(conf);
     return fs.exists(new Path(path));
 }

 /**
  * 判断目录是否为空
  * true: 空,false: 非空
  */
 public static boolean isDirEmpty(Configuration conf, String remoteDir) throws IOException {
     FileSystem fs = FileSystem.get(conf);
     Path dirPath = new Path(remoteDir);
     RemoteIterator<LocatedFileStatus> remoteIterator = fs.listFiles(dirPath, true);
     return !remoteIterator.hasNext();
 }

 /**
  * 创建目录
  */
 public static boolean mkdir(Configuration conf, String remoteDir) throws IOException {
     FileSystem fs = FileSystem.get(conf);
     Path dirPath = new Path(remoteDir);
     boolean result = fs.mkdirs(dirPath);
     fs.close();
     return result;
 }

 /**
 * 删除目录
  */
 public static boolean rmDir(Configuration conf, String remoteDir) throws IOException {
     FileSystem fs = FileSystem.get(conf);
     Path dirPath = new Path(remoteDir);
     /* 第二个参数表示是否递归删除所有文件 */
     boolean result = fs.delete(dirPath, true);
     fs.close();
     return result;
 }

 /**
  * 主函数
  */
 public static void main(String[] args) {
     Configuration conf = new Configuration();
 conf.set("fs.default.name","hdfs://localhost:9000");
     String remoteDir = "/user/hadoop/input";    // HDFS目录
     Boolean forceDelete = false;  // 是否强制删除

     try {
         /* 判断目录是否存在,不存在则创建,存在则删除 */
         if ( !HdfsApi.test(conf, remoteDir) ) {
             HdfsApi.mkdir(conf, remoteDir); // 创建目录
             System.out.println("创建目录: " + remoteDir);
         } else {
             if ( HdfsApi.isDirEmpty(conf, remoteDir) || forceDelete ) { // 目录为空或强制删除
                 HdfsApi.rmDir(conf, remoteDir);
                 System.out.println("删除目录: " + remoteDir);
             } else  { // 目录不为空
                 System.out.println("目录不为空,不删除: " + remoteDir);
             }
         }
     } catch (Exception e) {
         e.printStackTrace();
     }
 }
}

在这里插入图片描述

(2) 向HDFS中指定的文件追加内容,由用户指定内容追加到原有文件的开头或结尾;
Shell命令实现:
在这里插入图片描述
• 追加到文件末尾

hdfs dfs -appendToFile local.txt text.txt 

在这里插入图片描述
在这里插入图片描述
• 追加到文件开头

hdfs dfs -copyFromLocal -f local.txt /desText.txt

在这里插入图片描述
Java实现:

import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.*;import java.io.*;public class HdfsApi {
 /**
  * 判断路径是否存在
  */
 public static boolean test(Configuration conf, String path) throws IOException {
     FileSystem fs = FileSystem.get(conf);
     return fs.exists(new Path(path));
 }

 /**
  * 追加文本内容
  */
 public static void appendContentToFile(Configuration conf, String content, String remoteFilePath) throws IOException {
     FileSystem fs = FileSystem.get(conf);
     Path remotePath = new Path(remoteFilePath);
     /* 创建一个文件输出流,输出的内容将追加到文件末尾 */
     FSDataOutputStream out = fs.append(remotePath);
     out.write(content.getBytes());
     out.close();
     fs.close();
}

 /**
  * 追加文件内容
  */
 public static void appendToFile(Configuration conf, String localFilePath, String remoteFilePath) throws IOException {
     FileSystem fs = FileSystem.get(conf);
     Path remotePath = new Path(remoteFilePath);
     /* 创建一个文件读入流 */
     FileInputStream in = new FileInputStream(localFilePath);
     /* 创建一个文件输出流,输出的内容将追加到文件末尾 */
     FSDataOutputStream out = fs.append(remotePath);
     /* 读写文件内容 */
     byte[] data = new byte[1024];
     int read = -1;
     while ( (read = in.read(data)) > 0 ) {
         out.write(data, 0, read);
     }
     out.close();
     in.close();
     fs.close();
 }

 /**
  * 移动文件到本地
  * 移动后,删除源文件
  */
 public static void moveToLocalFile(Configuration conf, String remoteFilePath, String localFilePath) throws IOException {
     FileSystem fs = FileSystem.get(conf);
     Path remotePath = new Path(remoteFilePath);
     Path localPath = new Path(localFilePath);
     fs.moveToLocalFile(remotePath, localPath);
 }

 /**
  * 创建文件
  */
 public static void touchz(Configuration conf, String remoteFilePath) throws IOException {
     FileSystem fs = FileSystem.get(conf);
     Path remotePath = new Path(remoteFilePath);
     FSDataOutputStream outputStream = fs.create(remotePath);
     outputStream.close();
     fs.close();
 }

 /**
  * 主函数
  */
 public static void main(String[] args) {
     Configuration conf = new Configuration();
 conf.set("fs.default.name","hdfs://localhost:9000");
     String remoteFilePath = "/user/hadoop/text.txt";    // HDFS文件
     String content = "新追加的内容\n";
     String choice = "after";         //追加到文件末尾//        
String choice = "before";    // 追加到文件开头

     try {
         /* 判断文件是否存在 */
         if ( !HdfsApi.test(conf, remoteFilePath) ) {
             System.out.println("文件不存在: " + remoteFilePath);
         } else {
             if ( choice.equals("after") ) { // 追加在文件末尾
                 HdfsApi.appendContentToFile(conf, content, remoteFilePath);
                 System.out.println("已追加内容到文件末尾" + remoteFilePath);
             } else if ( choice.equals("before") )  { // 追加到文件开头
                 /* 没有相应的api可以直接操作,因此先把文件移动到本地,创建一个新的HDFS,再按顺序追加内容 */
                 String localTmpPath = "/user/hadoop/tmp.txt";
                 HdfsApi.moveToLocalFile(conf, remoteFilePath, localTmpPath);  // 移动到本地
                 HdfsApi.touchz(conf, remoteFilePath);    // 创建一个新文件
                 HdfsApi.appendContentToFile(conf, content, remoteFilePath);   // 先写入新内容
                 HdfsApi.appendToFile(conf, localTmpPath, remoteFilePath);   // 再写入原来内容
                 System.out.println("已追加内容到文件开头: " + remoteFilePath);
             }
         }
     } catch (Exception e) {
         e.printStackTrace();
     }
 }
}

(3) 删除HDFS中指定的文件;
Shell命令实现:

hdfs dfs -rm text.txt

Java实现:

import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.*;import java.io.*;public class HdfsApi {
 /**
  * 删除文件
  */
 public static boolean rm(Configuration conf, String remoteFilePath) throws IOException {
     FileSystem fs = FileSystem.get(conf);
     Path remotePath = new Path(remoteFilePath);
     boolean result = fs.delete(remotePath, false);
     fs.close();
     return result;
 }

 /**
  * 主函数
  */
 public static void main(String[] args) {
     Configuration conf = new Configuration();
 conf.set("fs.default.name","hdfs://localhost:9000");
     String remoteFilePath = "/user/hadoop/text.txt";    // HDFS文件

     try {
         if ( HdfsApi.rm(conf, remoteFilePath) ) {
             System.out.println("文件删除: " + remoteFilePath);
         } else {
             System.out.println("操作失败(文件不存在或删除失败)");
         }
     } catch (Exception e) {
         e.printStackTrace();
     }
 }
}

在这里插入图片描述

(4) 删除HDFS中指定的目录,由用户指定目录中如果存在文件时是否删除目录;
Shell命令实现:
• 删除目录(如果目录非空则会提示not empty,不执行删除)

hdfs dfs -rmdir dir1/dir2 

在这里插入图片描述

• 强制删除目录

hdfs dfs -rm -R /dir1/dir2 

在这里插入图片描述

Java实现:

import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.*;import java.io.*;public class HdfsApi {
 /**
  * 判断目录是否为空
  * true: 空,false: 非空
  */
 public static boolean isDirEmpty(Configuration conf, String remoteDir) throws IOException {FileSystem fs = FileSystem.get(conf);
     Path dirPath = new Path(remoteDir);
     RemoteIterator<LocatedFileStatus> remoteIterator = fs.listFiles(dirPath, true);
     return !remoteIterator.hasNext();
 }

 /**
  * 删除目录
  */
 public static boolean rmDir(Configuration conf, String remoteDir, boolean recursive) throws IOException {
     FileSystem fs = FileSystem.get(conf);
     Path dirPath = new Path(remoteDir);
     /* 第二个参数表示是否递归删除所有文件 */
     boolean result = fs.delete(dirPath, recursive);
     fs.close();
     return result;
 }

 /**
  * 主函数
  */
 public static void main(String[] args) {
     Configuration conf = new Configuration();
 conf.set("fs.default.name","hdfs://localhost:9000");
     String remoteDir = "/user/hadoop/dir1/dir2";    // HDFS目录
     Boolean forceDelete = false;  // 是否强制删除

     try {
         if ( !HdfsApi.isDirEmpty(conf, remoteDir) && !forceDelete ) {
             System.out.println("目录不为空,不删除");
         } else {
             if ( HdfsApi.rmDir(conf, remoteDir, forceDelete) ) {
                 System.out.println("目录已删除: " + remoteDir);
             } else {
                 System.out.println("操作失败");
             }
         }
     } catch (Exception e) {
         e.printStackTrace();
     }
 }
}

在这里插入图片描述

(5) 在HDFS中,将文件从源路径移动到目的路径。
Shell命令实现:

hdfs dfs -mv /desText.txt /dir1 

在这里插入图片描述
Java实现:

import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.*;import java.io.*;public class HdfsApi {
 /**
  * 移动文件
  */
 public static boolean mv(Configuration conf, String remoteFilePath, String remoteToFilePath) throws IOException {
     FileSystem fs = FileSystem.get(conf);
     Path srcPath = new Path(remoteFilePath);
     Path dstPath = new Path(remoteToFilePath);
     boolean result = fs.rename(srcPath, dstPath);
     fs.close();
     return result;
 }

 /**
  * 主函数
  */
 public static void main(String[] args) {
     Configuration conf = new Configuration();
 conf.set("fs.default.name","hdfs://localhost:9000");
     String remoteFilePath = "hdfs:///user/hadoop/text.txt";    // 源文件HDFS路径
     String remoteToFilePath = "hdfs:///user/hadoop/input";    // 目的HDFS路径

     try {
         if ( HdfsApi.mv(conf, remoteFilePath, remoteToFilePath) ) {
             System.out.println("将文件 " + remoteFilePath + " 移动到 " + remoteToFilePath);
         } else {
                 System.out.println("操作失败(源文件不存在或移动失败)");
         }
     } catch (Exception e) {
         e.printStackTrace();
     }
 }
}

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值