实验1
熟悉常用的Linux操作和Hadoop操作
1.实验目的
Hadoop运行在Linux系统上,因此,需要学习实践一些常用的Linux命令。本实验旨在熟悉常用的Linux操作和Hadoop操作,为顺利开展后续其他实验奠定基础。
2.实验平台
(1)操作系统:Linux(建议Ubuntu16.04或Ubuntu18.04);
(2)Hadoop版本:3.1.3。
3.实验步骤
1.熟悉常用的Linux操作
1)cd命令:切换目录
(1) 切换到目录“/usr/local”
(2) 切换到当前目录的上一级目录
(3) 切换到当前登录Linux系统的用户的自己的主文件夹
2)ls命令:查看文件与目录
查看目录“/usr”下的所有文件和目录
3)mkdir命令:新建目录
(1)进入“/tmp”目录,创建一个名为“a”的目录,并查看“/tmp”目录下已经存在哪些目录
(2)进入“/tmp”目录,创建目录“a1/a2/a3/a4”
4)rmdir命令:删除空的目录
(1)将上面创建的目录a(在“/tmp”目录下面)删除
(2)删除上面创建的目录“a1/a2/a3/a4” (在“/tmp”目录下面),然后查看“/tmp”目录下面存在哪些目录
5)cp命令:复制文件或目录
(1)将当前用户的主文件夹下的文件.bashrc复制到目录“/usr”下,并重命名为bashrc1
(2)在目录“/tmp”下新建目录test,再把这个目录复制到“/usr”目录下
6)mv命令:移动文件与目录,或更名
(1)将“/usr”目录下的文件bashrc1移动到“/usr/test”目录下
(2)将“/usr”目录下的test目录重命名为test2
7)rm命令:移除文件或目录
(1)将“/usr/test2”目录下的bashrc1文件删除
(2)将“/usr”目录下的test2目录删除
8)cat命令:查看文件内容
查看当前用户主文件夹下的.bashrc文件内容
9)tac命令:反向查看文件内容
反向查看当前用户主文件夹下的.bashrc文件的内容
10)more命令:一页一页翻动查看
翻页查看当前用户主文件夹下的.bashrc文件的内容
11)head命令:取出前面几行
(1)查看当前用户主文件夹下.bashrc文件内容前20行
(2)查看当前用户主文件夹下.bashrc文件内容,后面50行不显示,只显示前面几行
12)tail命令:取出后面几行
(1)查看当前用户主文件夹下.bashrc文件内容最后20行
(2)查看当前用户主文件夹下.bashrc文件内容,并且只列出50行以后的数据
13)touch命令:修改文件时间或创建新文件
(1)在“/tmp”目录下创建一个空文件hello,并查看文件时间
(2)修改hello文件,将文件时间整为5天前
14)chown命令:修改文件所有者权限
将hello文件所有者改为root帐号,并查看属性
15)find命令:文件查找
找出主文件夹下文件名为.bashrc的文件
16)tar命令:压缩命令
(1)在根目录“/”下新建文件夹test,然后在根目录“/”下打包成test.tar.gz
(2)把上面的test.tar.gz压缩包,解压缩到“/tmp”目录
17)grep命令:查找字符串
从“~/.bashrc”文件中查找字符串'examples'
18)配置环境变量
(1)请在“~/.bashrc”中设置,配置Java环境变量
(2)查看JAVA_HOME变量的值
2.熟悉常用的Hadoop操作
(1)使用hadoop用户登录Linux系统,启动Hadoop(Hadoop的安装目录为“/usr/local/hadoop”),为hadoop用户在HDFS中创建用户目录“/user/hadoop”
(2)接着在HDFS的目录“/user/hadoop”下,创建test文件夹,并查看文件列表
(3)将Linux系统本地的“~/.bashrc”文件上传到HDFS的test文件夹中,并查看test
(4)将HDFS文件夹test复制到Linux系统本地文件系统的“/usr/local/hadoop”目录下
4.实验报告
|
题目: |
熟悉常用的Linux操作和Hadoop操作 |
姓名 |
|
日期 |
|
实验环境: (2)Hadoop版本:2.7.3。 |
||||
|
实验内容与完成情况: 1)cd命令:切换目录 (4) 切换到目录“/usr/local” (5) 切换到当前目录的上一级目录 (6) 切换到当前登录Linux系统的用户的自己的主文件夹 实验截图:
2)ls命令:查看文件与目录 查看目录“/usr”下的所有文件和目录
3)mkdir命令:新建目录 (1)进入“/tmp”目录,创建一个名为“a”的目录,并查看“/tmp”目录下已经存在哪些目录
(2)进入“/tmp”目录,创建目录“a1/a2/a3/a4”
为了显示出/a1/a2/a3/a4 我分别再使用cd命令和ls命令确认已经建立以上目录
4)rmdir命令:删除空的目录 (1)将上面创建的目录a(在“/tmp”目录下面)删除
文件目录下没有a,已成功删除 (3)删除上面创建的目录“a1/a2/a3/a4” (在“/tmp”目录下面),然后查看“/tmp”目录下面存在哪些目录
5)cp命令:复制文件或目录 (1)将当前用户的主文件夹下的文件.bashrc复制到目录“/usr”下,并重命名为bashrc1
(3)在目录“/tmp”下新建目录test,再把这个目录复制到“/usr”目录下
6)mv命令:移动文件与目录,或更名 (1)将“/usr”目录下的文件bashrc1移动到“/usr/test”目录下
(3)将“/usr”目录下的test目录重命名为test2
7)rm命令:移除文件或目录 (1)将“/usr/test2”目录下的bashrc1文件删除
已成功删除 (3)将“/usr”目录下的test2目录删除
8)cat命令:查看文件内容 查看当前用户主文件夹下的.bashrc文件内容
9)tac命令:反向查看文件内容 反向查看当前用户主文件夹下的.bashrc文件的内容
10)more命令:一页一页翻动查看 翻页查看当前用户主文件夹下的.bashrc文件的内容
11)head命令:取出前面几行 (1)查看当前用户主文件夹下.bashrc文件内容前20行
(3)查看当前用户主文件夹下.bashrc文件内容,后面50行不显示,只显示前面几行
因为我的.bashrc文件内容总共没有五十行,所以在这条命令输完后未显示内容 12)tail命令:取出后面几行 (1)查看当前用户主文件夹下.bashrc文件内容最后20行
(3)查看当前用户主文件夹下.bashrc文件内容,并且只列出50行以后的数据
13)touch命令:修改文件时间或创建新文件 (1)在“/tmp”目录下创建一个空文件hello,并查看文件时间
发现一个时区和时间对不上的问题,然后去查了一下资料,发现我的NTP服务未启动,下面是命令正确的时间:
(2)修改hello文件,将文件时间整为5天前
14)chown命令:修改文件所有者权限 将hello文件所有者改为root帐号,并查看属性
15)find命令:文件查找 找出主文件夹下文件名为.bashrc的文件
16)tar命令:压缩命令 (1)在根目录“/”下新建文件夹test,然后在根目录“/”下打包成test.tar.gz
(2)把上面的test.tar.gz压缩包,解压缩到“/tmp”目录
17)grep命令:查找字符串 从“~/.bashrc”文件中查找字符串'examples'
18)配置环境变量 (1)请在“~/.bashrc”中设置,配置Java环境变量 (2)查看JAVA_HOME变量的值
2.熟悉常用的Hadoop操作 (1)使用hadoop用户登录Linux系统,启动Hadoop(Hadoop的安装目录为“/usr/local/hadoop”),为hadoop用户在HDFS中创建用户目录“/user/hadoop”
(2)接着在HDFS的目录“/user/hadoop”下,创建test文件夹,并查看文件列表
(3)将Linux系统本地的“~/.bashrc”文件上传到HDFS的test文件夹中,并查看test
(4)将HDFS文件夹test复制到Linux系统本地文件系统的“/usr/local/hadoop”目录下 cd /usr/local/hadoop ./bin/hdfs dfs -get test ./ |
||||
|
出现的问题: |
||||
|
解决方案(列出遇到的问题和解决办法,列出没有解决的问题):
发现一个时区和时间对不上的问题,然后去查了一下资料,发现我的NTP服务未启动,下面是命令正确的时间:
|
||||
实验2
熟悉常用的HDFS操作
1.实验目的
(1)理解HDFS在Hadoop体系结构中的角色;
(2)熟练使用HDFS操作常用的Shell命令;
(3)熟悉HDFS操作常用的Java API。
2. 实验平台
(1)操作系统:Linux(建议Ubuntu16.04或Ubuntu18.04);
(2)Hadoop版本:3.1.3;
(3)JDK版本:1.8;
(4)Java IDE:Eclipse。
3. 实验步骤
(一)编程实现以下功能,并利用Hadoop提供的Shell命令完成相同任务:
(1) 向HDFS中上传任意文本文件,如果指定的文件在HDFS中已经存在,则由用户来指定是追加到原有文件末尾还是覆盖原有的文件;
(2) 从HDFS中下载指定文件,如果本地文件与要下载的文件名称相同,则自动对下载的文件重命名;
(3) 将HDFS中指定文件的内容输出到终端中;
(4) 显示HDFS中指定的文件的读写权限、大小、创建时间、路径等信息;
(5) 给定HDFS中某一个目录,输出该目录下的所有文件的读写权限、大小、创建时间、路径等信息,如果该文件是目录,则递归输出该目录下所有文件相关信息;
(6) 提供一个HDFS内的文件的路径,对该文件进行创建和删除操作。如果文件所在目录不存在,则自动创建目录;
(7) 提供一个HDFS的目录的路径,对该目录进行创建和删除操作。创建目录时,如果目录文件所在目录不存在,则自动创建相应目录;删除目录时,由用户指定当该目录不为空时是否还删除该目录;
(8) 向HDFS中指定的文件追加内容,由用户指定内容追加到原有文件的开头或结尾;
(9) 删除HDFS中指定的文件;
(10) 在HDFS中,将文件从源路径移动到目的路径。
(二)编程实现一个类“MyFSDataInputStream”,该类继承“org.apache.hadoop.fs.FSDataInputStream”,要求如下:实现按行读取HDFS中指定文件的方法“readLine()”,如果读到文件末尾,则返回空,否则返回文件一行的文本。
(三)查看Java帮助手册或其它资料,用“java.net.URL”和“org.apache.hadoop.fs.FsURLStreamHandlerFactory”编程完成输出HDFS中指定文件的文本到终端中。
4.实验报告
|
题目: |
熟悉常用的HDFS操作 |
姓名 |
|
日期 |
|
实验环境: (1)操作系统:Linux(centOS7); (2)Hadoop版本:2.7.3; (3)JDK版本:1.8; (4)Java IDE:Idea。 |
||||
|
实验内容与完成情况: (1) 向HDFS中上传任意文本文件,如果指定的文件在HDFS中已经存在,则由用户来指定是追加到原有文件末尾还是覆盖原有的文件; Java代码:①HDFSApi.java package HDFSApi; // 包名声明
import org.apache.hadoop.conf.Configuration; // 引入Hadoop配置类 import org.apache.hadoop.fs.*; // 引入Hadoop文件系统相关类 import java.io.*; // 引入Java文件I/O类库
import HDFSApi.SCP; // 引入自定义的SCP类,用于文件下载
public class HDFSApi { // HDFSApi类定义
/** * 判断路径是否存在 * * @param conf Hadoop配置 * @param path HDFS上的路径 * @return 如果路径存在,返回true,否则返回false */ public static boolean test(Configuration conf, String path) throws IOException { FileSystem fs = FileSystem.get(conf); // 获取Hadoop文件系统对象 return fs.exists(new Path(path)); // 判断路径是否存在 }
/** * 复制文件到指定路径 * 如果路径已存在,则进行覆盖 * * @param conf Hadoop配置 * @param localFilePath 本地文件路径 * @param remoteFilePath 目标HDFS路径 */ public static void copyFromLocalFile(Configuration conf, String localFilePath, String remoteFilePath) throws IOException { FileSystem fs = FileSystem.get(conf); // 获取Hadoop文件系统对象 Path localPath = new Path(localFilePath); // 本地文件路径 Path remotePath = new Path(remoteFilePath); // 远程HDFS路径 // 使用HDFS的copyFromLocalFile方法进行文件上传,第一个参数为是否删除源文件,第二个参数为是否覆盖 fs.copyFromLocalFile(false, true, localPath, remotePath); fs.close(); // 关闭文件系统对象 }
/** * 追加文件内容 * * @param conf Hadoop配置 * @param localFilePath 本地文件路径 * @param remoteFilePath 目标HDFS路径 */ public static void appendToFile(Configuration conf, String localFilePath, String remoteFilePath) throws IOException { FileSystem fs = FileSystem.get(conf); // 获取Hadoop文件系统对象 Path remotePath = new Path(remoteFilePath); // 远程HDFS路径 // 创建一个输入流来读取本地文件 FileInputStream in = new FileInputStream(localFilePath); // 创建一个输出流来追加数据到HDFS文件末尾 FSDataOutputStream out = fs.append(remotePath); byte[] data = new byte[1024]; // 定义字节数组,用于缓存读取的数据 int read = -1; // 循环读取本地文件内容,并将其写入HDFS文件 while ((read = in.read(data)) > 0) { out.write(data, 0, read); // 将读取的数据写入HDFS } out.close(); // 关闭输出流 in.close(); // 关闭输入流 fs.close(); // 关闭文件系统对象 }
/** * 主函数 */ public static void main(String[] args) throws IOException {
// 使用SCP类将Linux上的文件下载到Windows上(假设SCP.get()已经实现) SCP.get();
// 创建Hadoop配置对象 Configuration conf = new Configuration(); // 设置HDFS的URI conf.set("fs.default.name", "hdfs://192.168.43.200:9000");
String localFilePath = "D:\\local.txt"; // 本地文件路径 String remoteFilePath = "/user/hadoop/text.txt"; // 目标HDFS路径 String choice = "append"; // 用户选择操作:append为追加,overwrite为覆盖
try { // 判断文件是否存在 Boolean fileExists = false; if (HDFSApi.test(conf, remoteFilePath)) { // 调用test方法判断路径是否存在 fileExists = true; System.out.println(remoteFilePath + " 已存在."); } else { System.out.println(remoteFilePath + " 不存在."); }
// 根据用户选择的操作进行不同处理 if (!fileExists) { // 如果文件不存在,执行上传操作 HDFSApi.copyFromLocalFile(conf, localFilePath, remoteFilePath); // 上传文件 System.out.println(localFilePath + " 已上传至 " + remoteFilePath); } else if (choice.equals("overwrite")) { // 如果选择覆盖,执行覆盖操作 HDFSApi.copyFromLocalFile(conf, localFilePath, remoteFilePath); // 上传文件并覆盖 System.out.println(localFilePath + " 已覆盖 " + remoteFilePath); } else if (choice.equals("append")) { // 如果选择追加,执行追加操作 HDFSApi.appendToFile(conf, localFilePath, remoteFilePath); // 追加文件内容 System.out.println(localFilePath + " 已追加至 " + remoteFilePath); } } catch (Exception e) { e.printStackTrace(); // 如果发生异常,打印异常信息 } } } ② SCP.java package HDFSApi; // 定义包名,表示该类属于 HDFSApi 包
import java.io.IOException; // 导入 IOException 类,用于处理输入输出异常 import ch.ethz.ssh2.Connection; // 导入 Connection 类,用于建立与远程主机的 SSH 连接 import ch.ethz.ssh2.SCPClient; // 导入 SCPClient 类,用于执行 SCP(安全复制)操作
public class SCP { // 定义一个名为 SCP 的类
// 定义一个静态方法 get(),抛出 IOException 异常 public static void get() throws IOException {
// 创建一个 Connection 对象 conn,连接到远程主机(IP 地址为 192.168.43.200) Connection conn = new Connection("192.168.43.200");
// 使用 connect() 方法建立与远程主机的 SSH 连接 conn.connect();
// 使用 authenticateWithPassword() 方法验证用户名和密码,返回是否认证成功 boolean isAuthenticated = conn.authenticateWithPassword("root", "123456");
// 如果认证失败,则抛出 IOException 异常 if (isAuthenticated == false) throw new IOException("Authentication failed.");
// 创建一个 SCPClient 对象 client,传入已建立的 SSH 连接 conn SCPClient client = new SCPClient(conn);
// 使用 client 的 get() 方法从远程主机下载文件 "/root/local.txt" 到本地 D:\ 目录 client.get("/root/local.txt", "D:\\");
// 关闭 SSH 连接 conn.close(); } }
(2) 从HDFS中下载指定文件,如果本地文件与要下载的文件名称相同,则自动对下载的文件重命名; Java代码: HDFSApi.java package HDFSApi; // 定义包名,HDFSApi 是一个包的名称
import org.apache.hadoop.conf.Configuration; // 导入 Hadoop 配置类 import org.apache.hadoop.fs.*; // 导入 Hadoop 文件系统相关类 import java.io.*; // 导入 Java IO 类
public class HDFSApi { // 定义主类 HDFSApi
/** * 下载文件到本地 * 判断本地路径是否已存在,若已存在,则自动进行重命名 */ public static void copyToLocal(Configuration conf, String remoteFilePath, String localFilePath) throws IOException { // 获取文件系统对象,通过传入的配置对象获取 HDFS 文件系统实例 FileSystem fs = FileSystem.get(conf);
// 定义远程文件路径(HDFS 文件路径) Path remotePath = new Path(remoteFilePath);
// 定义本地文件路径(存储文件的本地路径) File f = new File(localFilePath);
/* 如果文件名存在,自动重命名(在文件名后面加上 _0, _1 ...) */ if (f.exists()) { // 如果本地路径的文件已经存在 System.out.println(localFilePath + " 已存在."); // 打印已存在的文件路径 Integer i = 0; // 初始化计数器,用于生成新文件名 while (true) { // 循环查找未存在的文件名 // 创建一个新文件对象,文件名后加上 _i 来避免文件名冲突 f = new File(localFilePath + "_" + i.toString()); if (!f.exists()) { // 如果该文件名不存在 // 生成一个新的本地文件路径(带有编号) localFilePath = localFilePath + "_" + i.toString(); break; // 退出循环 } i++; // 文件名已存在,增加计数器并继续查找 } System.out.println("将重新命名为: " + localFilePath); // 打印重命名后的文件路径 }
// 下载文件到本地路径 Path localPath = new Path(localFilePath); // 将本地路径转换为 Path 对象 fs.copyToLocalFile(remotePath, localPath); // 调用 HDFS API 下载文件到本地 fs.close(); // 关闭文件系统实例 }
/** * 主函数 */ public static void main(String[] args) { // 创建 Hadoop 配置对象 Configuration conf = new Configuration(); // 设置 HDFS 的默认文件系统地址 conf.set("fs.default.name","hdfs://192.168.43.200:9000");
// 本地存储文件的路径 String localFilePath = "D://text.txt"; // HDFS 上文件的路径 String remoteFilePath = "/user/hadoop/text.txt";
try { // 调用 copyToLocal 方法,将文件从 HDFS 下载到本地 HDFSApi.copyToLocal(conf, remoteFilePath, localFilePath); // 输出下载完成的提示信息 System.out.println("下载完成"); } catch (Exception e) { // 如果发生异常,打印异常信息 e.printStackTrace(); } } }
(3) 将HDFS中指定文件的内容输出到终端中; Java代码: package HDFSApi; // 定义包名
import org.apache.hadoop.conf.Configuration; // 导入Hadoop配置类,用于设置HDFS的连接信息 import org.apache.hadoop.fs.*; // 导入Hadoop的文件系统相关类,用于操作HDFS import java.io.*; // 导入Java I/O类,用于文件操作
public class HDFSApi { // 定义HDFSApi类
/** * 读取HDFS文件的内容 * @param conf Hadoop的配置信息 * @param remoteFilePath HDFS上文件的路径 * @throws IOException 可能抛出的IO异常 */ public static void cat(Configuration conf, String remoteFilePath) throws IOException { // 获取文件系统的实例,这里使用HDFS文件系统 FileSystem fs = FileSystem.get(conf);
// 创建一个HDFS文件的路径对象 Path remotePath = new Path(remoteFilePath);
// 打开指定路径的文件,返回输入流 FSDataInputStream in = fs.open(remotePath);
// 使用缓冲字符输入流读取文件内容 BufferedReader d = new BufferedReader(new InputStreamReader(in));
// 声明一个字符串变量,用来存储每一行的内容 String line = null;
// 循环读取文件的每一行,直到文件末尾 while ((line = d.readLine()) != null) { // 打印每一行的内容到控制台 System.out.println(line); }
// 关闭BufferedReader d.close();
// 关闭输入流 in.close();
// 关闭文件系统 fs.close(); }
/** * 主函数,用于执行读取HDFS文件的操作 * @param args 命令行参数 */ public static void main(String[] args) { // 创建Hadoop配置对象 Configuration conf = new Configuration();
// 设置HDFS的默认文件系统地址,这里是本地的HDFS集群地址 conf.set("fs.default.name", "hdfs://localhost:900
(4) 显示HDFS中指定的文件的读写权限、大小、创建时间、路径等信息; Java代码: package HDFSApi; // 定义包名,表示该类属于 HDFSApi 包
import org.apache.hadoop.conf.Configuration; // 导入 Hadoop 配置类,用于配置文件系统 import org.apache.hadoop.fs.*; // 导入 Hadoop 文件系统相关的类 import java.io.*; // 导入 Java 输入输出库,用于异常处理等 import java.text.SimpleDateFormat; // 导入日期格式化类,用于将时间戳转换为日期字符串
public class HDFSApi { // 定义类 HDFSApi
/** * 显示指定文件的信息 * 这个方法会显示指定 HDFS 文件的路径、权限、大小以及修改时间 */ public static void ls(Configuration conf, String remoteFilePath) throws IOException { // 定义 ls 方法,接收配置和文件路径作为参数 FileSystem fs = FileSystem.get(conf); // 获取 HDFS 文件系统的实例 Path remotePath = new Path(remoteFilePath); // 创建一个 HDFS 路径对象,表示要查询的文件路径 FileStatus[] fileStatuses = fs.listStatus(remotePath); // 获取指定路径下文件的状态信息,返回 FileStatus 数组 for (FileStatus s : fileStatuses) { // 遍历文件状态信息数组 System.out.println("路径: " + s.getPath().toString()); // 打印文件的路径 System.out.println("权限: " + s.getPermission().toString()); // 打印文件的权限 System.out.println("大小: " + s.getLen()); // 打印文件的大小 /* 返回的是时间戳,转化为时间日期格式 */ Long timeStamp = s.getModificationTime(); // 获取文件的修改时间戳 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 创建日期格式化对象,设置日期格式 String date = format.format(timeStamp); // 将时间戳格式化为日期字符串 System.out.println("时间: " + date); // 打印文件的修改时间 } fs.close(); // 关闭文件系统对象,释放资源 }
/** * 主函数 * 该函数是程序的入口,执行文件信息查询 */ public static void main(String[] args) { // 主函数入口 Configuration conf = new Configuration(); // 创建一个 Hadoop 配置对象 conf.set("fs.default.name", "hdfs://192.168.43.200:9000"); // 设置 HDFS 文件系统的 URI,指定 Hadoop 集群的地址 String remoteFilePath = "/user/hadoop/text.txt"; // HDFS 上的文件路径,指定要查询的文件
try { // 使用 try-catch 块捕获异常 System.out.println("读取文件信息: " + remoteFilePath); // 打印正在读取的文件路径 HDFSApi.ls(conf, remoteFilePath); // 调用 ls 方法,显示文件的相关信息 System.out.println("\n 读取完成"); // 打印读取完成的消息 } catch (Exception e) { // 捕获并处理异常 e.printStackTrace(); // 打印异常堆栈信息,便于调试 } } }
(5) 给定HDFS中某一个目录,输出该目录下的所有文件的读写权限、大小、创建时间、路径等信息,如果该文件是目录,则递归输出该目录下所有文件相关信息; Java代码:package HDFSApi; // 定义包名,表示该类属于 HDFSApi 包
import org.apache.hadoop.conf.Configuration; // 导入 Hadoop 配置类,用于配置文件系统 import org.apache.hadoop.fs.*; // 导入 Hadoop 文件系统相关的类,用于操作文件 import java.io.*; // 导入 Java 输入输出库,处理异常 import java.text.SimpleDateFormat; // 导入日期格式化类,用于将时间戳转换为日期字符串
public class HDFSApi { // 定义类 HDFSApi
/** * 显示指定文件夹下所有文件的信息(递归) * 这个方法会递归地列出指定目录下的所有文件,并显示其路径、权限、大小和修改时间。 */ public static void lsDir(Configuration conf, String remoteDir) throws IOException { // 定义 lsDir 方法,接收配置和远程目录路径作为参数 FileSystem fs = FileSystem.get(conf); // 获取 HDFS 文件系统的实例 Path dirPath = new Path(remoteDir); // 创建一个 HDFS 路径对象,表示要查询的目录路径
/* 递归获取目录下的所有文件 */ RemoteIterator<LocatedFileStatus> remoteIterator = fs.listFiles(dirPath, true); // 获取目录下的所有文件(包括子目录中的文件),返回一个远程文件迭代器
/* 输出每个文件的信息 */ while (remoteIterator.hasNext()) { // 如果还有文件,继续遍历 FileStatus s = remoteIterator.next(); // 获取下一个文件的状态 System.out.println("路径: " + s.getPath().toString()); // 打印文件的路径 System.out.println("权限: " + s.getPermission().toString()); // 打印文件的权限 System.out.println("大小: " + s.getLen()); // 打印文件的大小 /* 返回的是时间戳, 转化为时间日期格式 */ Long timeStamp = s.getModificationTime(); // 获取文件的修改时间戳 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 创建日期格式化对象,设置日期格式 String date = format.format(timeStamp); // 将时间戳格式化为日期字符串 System.out.println("时间: " + date); // 打印文件的修改时间 System.out.println(); // 打印一个空行,分隔不同文件的信息 } fs.close(); // 关闭文件系统对象,释放资源 }
/** * 主函数 * 该函数是程序的入口,执行目录下所有文件信息的查询 */ public static void main(String[] args) { // 主函数入口 Configuration conf = new Configuration(); // 创建一个 Hadoop 配置对象 conf.set("fs.default.name", "hdfs://192.168.43.200:9000"); // 设置 HDFS 文件系统的 URI,指定 Hadoop 集群的地址
String remoteDir = "/user/hadoop"; // HDFS 上的目录路径,指定要查询的目录
try { // 使用 try-catch 块捕获异常 System.out.println("(递归)读取目录下所有文件的信息: " + remoteDir); // 打印正在读取的目录路径 HDFSApi.lsDir(conf, remoteDir); // 调用 lsDir 方法,显示该目录下所有文件的信息(递归) System.out.println("读取完成"); // 打印读取完成的消息 } catch (Exception e) { // 捕获并处理异常 e.printStackTrace(); // 打印异常堆栈信息,便于调试 } } }
(6) 提供一个HDFS内的文件的路径,对该文件进行创建和删除操作。如果文件所在目录不存在,则自动创建目录; Java代码: package HDFSApi; // 定义包名,表示该类属于 HDFSApi 包
import org.apache.hadoop.conf.Configuration; // 导入 Hadoop 配置类,用于配置文件系统 import org.apache.hadoop.fs.*; // 导入 Hadoop 文件系统相关类,用于操作文件和目录 import java.io.*; // 导入 Java 输入输出库,用于处理异常
public class HDFSApi { // 定义类 HDFSApi
/** * 判断路径是否存在 * 该方法检查指定的路径(文件或目录)是否存在于 HDFS 中 */ public static boolean test(Configuration conf, String path) throws IOException { // 定义 test 方法,接收 Hadoop 配置和路径作为参数 FileSystem fs = FileSystem.get(conf); // 获取 HDFS 文件系统实例 return fs.exists(new Path(path)); // 检查路径是否存在,返回布尔值 }
/** * 创建目录 * 该方法在 HDFS 上创建指定的目录 */ public static boolean mkdir(Configuration conf, String remoteDir) throws IOException { // 定义 mkdir 方法,接收配置和远程目录路径作为参数 FileSystem fs = FileSystem.get(conf); // 获取 HDFS 文件系统实例 Path dirPath = new Path(remoteDir); // 创建一个 HDFS 路径对象,表示要创建的目录路径 boolean result = fs.mkdirs(dirPath); // 创建目录,返回是否成功的布尔值 fs.close(); // 关闭文件系统实例,释放资源 return result; // 返回创建目录是否成功的结果 }
/** * 创建文件 * 该方法在 HDFS 上创建一个空文件 */ public static void touchz(Configuration conf, String remoteFilePath) throws IOException { // 定义 touchz 方法,接收配置和文件路径作为参数 FileSystem fs = FileSystem.get(conf); // 获取 HDFS 文件系统实例 Path remotePath = new Path(remoteFilePath); // 创建一个 HDFS 路径对象,表示要创建的文件路径 FSDataOutputStream outputStream = fs.create(remotePath); // 创建文件并获取输出流 outputStream.close(); // 关闭输出流,完成文件的创建 fs.close(); // 关闭文件系统实例,释放资源 }
/** * 删除文件 * 该方法删除 HDFS 上的指定文件 */ public static boolean rm(Configuration conf, String remoteFilePath) throws IOException { // 定义 rm 方法,接收配置和文件路径作为参数 FileSystem fs = FileSystem.get(conf); // 获取 HDFS 文件系统实例 Path remotePath = new Path(remoteFilePath); // 创建一个 HDFS 路径对象,表示要删除的文件路径 boolean result = fs.delete(remotePath, false); // 删除文件,第二个参数指定是否递归删除 fs.close(); // 关闭文件系统实例,释放资源 return result; // 返回文件删除是否成功的结果 }
/** * 主函数 * 该函数是程序的入口,用于演示文件和目录的操作(测试、删除、创建) */ public static void main(String[] args) { // 主函数入口 Configuration conf = new Configuration(); // 创建一个 Hadoop 配置对象 conf.set("fs.default.name", "hdfs://192.168.43.200:9000"); // 设置 HDFS 文件系统的 URI,指定 Hadoop 集群的地址
String remoteFilePath = "/user/hadoop/input/text.txt"; // HDFS 路径,指定要操作的文件路径 String remoteDir = "/user/hadoop/input"; // HDFS 路径,指定要操作的目录路径
try { // 使用 try-catch 块捕获异常 /* 判断路径是否存在,存在则删除,否则进行创建 */ if (HDFSApi.test(conf, remoteFilePath)) { // 检查文件路径是否存在 HDFSApi.rm(conf, remoteFilePath); // 如果文件存在,调用 rm 方法删除文件 System.out.println("删除路径: " + remoteFilePath); // 打印删除的路径 } else { // 如果文件不存在 if (!HDFSApi.test(conf, remoteDir)) { // 检查目录路径是否存在 HDFSApi.mkdir(conf, remoteDir); // 如果目录不存在,调用 mkdir 方法创建目录 System.out.println("创建文件夹: " + remoteDir); // 打印创建的目录路径 } HDFSApi.touchz(conf, remoteFilePath); // 创建文件 System.out.println("创建路径: " + remoteFilePath); // 打印创建的文件路径 } } catch (Exception e) { // 捕获异常并处理 e.printStackTrace(); // 打印异常的堆栈信息 } } }
(7) 提供一个HDFS的目录的路径,对该目录进行创建和删除操作。创建目录时,如果目录文件所在目录不存在,则自动创建相应目录;删除目录时,由用户指定当该目录不为空时是否还删除该目录; package HDFSApi; // 定义包名,表示该类属于 HDFSApi 包
import org.apache.hadoop.conf.Configuration; // 导入 Hadoop 配置类,用于配置文件系统 import org.apache.hadoop.fs.*; // 导入 Hadoop 文件系统相关类,用于操作文件和目录 import java.io.*; // 导入 Java 输入输出库,用于处理异常
public class HDFSApi { // 定义类 HDFSApi
/** * 判断路径是否存在 * 该方法检查指定的路径(文件或目录)是否存在于 HDFS 中 */ public static boolean test(Configuration conf, String path) throws IOException { // 定义 test 方法,接收配置和路径作为参数 FileSystem fs = FileSystem.get(conf); // 获取 HDFS 文件系统实例 return fs.exists(new Path(path)); // 返回路径是否存在的布尔值 }
/** * 判断目录是否为空 * 如果目录为空,则返回 true;如果目录非空,则返回 false。 */ public static boolean isDirEmpty(Configuration conf, String remoteDir) throws IOException { // 定义 isDirEmpty 方法,接收配置和目录路径作为参数 FileSystem fs = FileSystem.get(conf); // 获取 HDFS 文件系统实例 Path dirPath = new Path(remoteDir); // 创建一个 HDFS 路径对象,表示目录路径 RemoteIterator<LocatedFileStatus> remoteIterator = fs.listFiles(dirPath, true); // 列出目录下的文件(递归遍历子目录) return !remoteIterator.hasNext(); // 如果没有文件,表示目录为空,返回 true;否则返回 false }
/** * 创建目录 * 该方法在 HDFS 上创建指定目录 */ public static boolean mkdir(Configuration conf, String remoteDir) throws IOException { // 定义 mkdir 方法,接收配置和目录路径作为参数 FileSystem fs = FileSystem.get(conf); // 获取 HDFS 文件系统实例 Path dirPath = new Path(remoteDir); // 创建一个 HDFS 路径对象,表示要创建的目录路径 boolean result = fs.mkdirs(dirPath); // 使用 mkdirs 方法创建目录,返回是否成功的布尔值 fs.close(); // 关闭文件系统实例,释放资源 return result; // 返回目录创建是否成功的结果 }
/** * 删除目录 * 该方法删除 HDFS 上指定的目录,支持递归删除目录中的所有文件 */ public static boolean rmDir(Configuration conf, String remoteDir) throws IOException { // 定义 rmDir 方法,接收配置和目录路径作为参数 FileSystem fs = FileSystem.get(conf); // 获取 HDFS 文件系统实例 Path dirPath = new Path(remoteDir); // 创建一个 HDFS 路径对象,表示要删除的目录路径 /* 第二个参数表示是否递归删除所有文件 */ boolean result = fs.delete(dirPath, true); // 删除目录及其内容,`true` 表示递归删除 fs.close(); // 关闭文件系统实例,释放资源 return result; // 返回目录删除是否成功的结果 }
/** * 主函数 * 该函数是程序的入口,用于演示如何操作 HDFS 上的目录(检查、创建、删除) */ public static void main(String[] args) { // 主函数入口 Configuration conf = new Configuration(); // 创建一个 Hadoop 配置对象 conf.set("fs.default.name", "hdfs://192.168.43.200:9000"); // 设置 HDFS 文件系统的 URI,指定 Hadoop 集群的地址
String remoteDir = "/user/hadoop/input"; // HDFS 上的目录路径,指定要操作的目录 Boolean forceDelete = false; // 是否强制删除目录,默认不强制删除
try { // 使用 try-catch 块捕获异常 /* 判断目录是否存在,不存在则创建,存在则删除 */ if (!HDFSApi.test(conf, remoteDir)) { // 检查目录是否存在 HDFSApi.mkdir(conf, remoteDir); // 如果目录不存在,调用 mkdir 方法创建目录 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(); // 打印异常的堆栈信息 } } }
(8) 向HDFS中指定的文件追加内容,由用户指定内容追加到原有文件的开头或结尾; package HDFSApi; // 定义包名 HDFSApi
import org.apache.hadoop.conf.Configuration; // 导入 Hadoop 配置类,用于读取和设置配置 import org.apache.hadoop.fs.*; // 导入 Hadoop 文件系统相关类,用于文件操作 import java.io.*; // 导入 Java 输入输出流类,用于文件读写操作
public class HDFSApi { // 定义 HDFSApi 类
/** * 判断路径是否存在 * 该方法检查指定路径(文件或目录)是否存在于 HDFS 中 */ public static boolean test(Configuration conf, String path) throws IOException { // 定义 test 方法,接收 Hadoop 配置和路径作为参数 FileSystem fs = FileSystem.get(conf); // 获取 HDFS 文件系统实例 return fs.exists(new Path(path)); // 检查路径是否存在,返回布尔值 }
/** * 追加文本内容到文件 * 该方法将给定的文本内容追加到指定的文件末尾 */ public static void appendContentToFile(Configuration conf, String content, String remoteFilePath) throws IOException { // 定义方法,接收配置、内容和文件路径作为参数 FileSystem fs = FileSystem.get(conf); // 获取 HDFS 文件系统实例 Path remotePath = new Path(remoteFilePath); // 创建 HDFS 文件路径对象 /* 创建一个文件输出流,输出的内容将追加到文件末尾 */ 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); // 获取 HDFS 文件系统实例 Path remotePath = new Path(remoteFilePath); // 创建 HDFS 文件路径对象 /* 创建一个文件读入流 */ FileInputStream in = new FileInputStream(localFilePath); // 创建本地文件输入流 /* 创建一个文件输出流,输出的内容将追加到文件末尾 */ FSDataOutputStream out = fs.append(remotePath); // 获取 HDFS 文件输出流,准备将内容追加到文件末尾 /* 读写文件内容 */ byte[] data = new byte[1024]; // 创建一个字节数组用于存储读取的数据 int read = -1; // 记录每次读取的字节数 if (in != null) { // 检查输入流是否为空 while ((read = in.read(data)) > 0) { // 从本地文件读取数据 out.write(data, 0, read); // 将读取到的数据写入 HDFS 文件 } } out.close(); // 关闭输出流 in.close(); // 关闭输入流 fs.close(); // 关闭文件系统实例 }
/** * 移动文件到本地 * 移动后,删除源文件 */ public static void moveToLocalFile(Configuration conf, String remoteFilePath, String localFilePath) throws IOException { // 定义方法,接收配置、远程文件路径和本地文件路径 FileSystem fs = FileSystem.get(conf); // 获取 HDFS 文件系统实例 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); // 获取 HDFS 文件系统实例 Path remotePath = new Path(remoteFilePath); // 创建 HDFS 文件路径对象 FSDataOutputStream outputStream = fs.create(remotePath); // 创建文件并获取输出流 outputStream.close(); // 关闭输出流 fs.close(); // 关闭文件系统实例 }
/** * 主函数 * 该函数是程序的入口,执行具体的操作(如文件追加内容、移动文件等) */ public static void main(String[] args) { // 主函数入口 Configuration conf = new Configuration(); // 创建 Hadoop 配置对象 conf.set("fs.default.name", "hdfs://192.168.43.200:9000"); // 设置 HDFS 地址,连接到指定的 Hadoop 集群
String remoteFilePath = "/user/hadoop/text.txt"; // HDFS 文件路径 String content = "新追加的内容\n"; // 要追加的文本内容 //String choice = "after"; // 追加到文件末尾 String choice = "before"; // 选择追加到文件开头,另一种选择是 "after" 追加到文件末尾
try { // 使用 try-catch 块捕获异常 /* 判断文件是否存在 */ 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); // 移动文件到本地 // 创建一个新的 HDFS 文件 HDFSApi.touchz(conf, remoteFilePath); // 创建新文件 // 先写入新内容到文件 HDFSApi.appendContentToFile(conf, content, remoteFilePath); // 追加内容到文件开头 // 再写入原来文件的内容 HDFSApi.appendToFile(conf, localTmpPath, remoteFilePath); // 追加原文件的内容到新文件 System.out.println("已追加内容到文件开头: " + remoteFilePath); // 打印提示信息 } } } catch (Exception e) { // 捕获并打印异常信息 e.printStackTrace(); // 打印异常的堆栈信息 } } }
追加到原文件末尾
追加到原文件开头
(9) 删除HDFS中指定的文件; package HDFSApi; // 定义包名 HDFSApi
import org.apache.hadoop.conf.Configuration; // 导入 Hadoop 配置类,用于配置 Hadoop 文件系统 import org.apache.hadoop.fs.*; // 导入 Hadoop 文件系统类,用于文件操作 import java.io.*; // 导入 Java IO 类,用于输入输出操作
public class HDFSApi { // 定义 HDFSApi 类
/** * 删除文件 * 该方法用于删除指定路径的 HDFS 文件 */ public static boolean rm(Configuration conf, String remoteFilePath) throws IOException { // 定义 rm 方法,接收 Hadoop 配置和文件路径 FileSystem fs = FileSystem.get(conf); // 获取 HDFS 文件系统实例 Path remotePath = new Path(remoteFilePath); // 创建一个路径对象,指定要删除的 HDFS 文件 boolean result = fs.delete(remotePath, false); // 删除文件,第二个参数表示是否递归删除(此处为 false,表示不递归) fs.close(); // 关闭文件系统,释放资源 return result; // 返回删除操作的结果(成功返回 true,失败返回 false) }
/** * 主函数 * 程序入口,执行文件删除操作 */ public static void main(String[] args) { // 主函数,程序的入口 Configuration conf = new Configuration(); // 创建 Hadoop 配置对象,用于设置文件系统信息 conf.set("fs.default.name", "hdfs://192.168.43.200:9000"); // 设置 HDFS 的 URI 地址,指向 Hadoop 集群中的 HDFS
String remoteFilePath = "/user/hadoop/text.txt"; // 设置要删除的 HDFS 文件路径
try { // 使用 try-catch 块捕获异常 // 调用 rm 方法删除文件,如果文件删除成功 if (HDFSApi.rm(conf, remoteFilePath)) { System.out.println("文件删除: " + remoteFilePath); // 输出删除成功的提示信息 } else { System.out.println("操作失败(文件不存在或删除失败)"); // 输出删除失败的提示信息 } } catch (Exception e) { // 捕获可能的异常 e.printStackTrace(); // 打印异常信息 } } }
(10) 在HDFS中,将文件从源路径移动到目的路径。 package HDFSApi; // 定义包名 HDFSApi
import org.apache.hadoop.conf.Configuration; // 导入 Hadoop 配置类,用于配置 Hadoop 文件系统 import org.apache.hadoop.fs.*; // 导入 Hadoop 文件系统类,用于文件操作 import java.io.*; // 导入 Java IO 类,用于输入输出操作
public class HDFSApi { // 定义 HDFSApi 类
/** * 移动文件 * 该方法用于将文件从源路径移动到目的路径 */ public static boolean mv(Configuration conf, String remoteFilePath, String remoteToFilePath) throws IOException { // 定义 mv 方法,接收 Hadoop 配置和源路径及目的路径 FileSystem fs = FileSystem.get(conf); // 获取 HDFS 文件系统实例,通过传入的配置对象 conf Path srcPath = new Path(remoteFilePath); // 创建一个 Path 对象表示源文件路径 Path dstPath = new Path(remoteToFilePath); // 创建一个 Path 对象表示目标文件路径 boolean result = fs.rename(srcPath, dstPath); // 使用 rename 方法将文件从源路径移动到目标路径,返回操作结果(成功返回 true,失败返回 false) fs.close(); // 关闭文件系统实例,释放资源 return result; // 返回移动操作的结果 }
/** * 主函数 * 程序入口,执行文件移动操作 */ public static void main(String[] args) { // 主函数,程序的入口 Configuration conf = new Configuration(); // 创建一个 Configuration 对象,用于设置 Hadoop 配置 conf.set("fs.default.name", "hdfs://192.168.43.200:9000"); // 设置 HDFS 的 URI 地址,用于连接到 Hadoop 集群的文件系统
String remoteFilePath = "hdfs:///user/hadoop/text.txt"; // 设置源文件的 HDFS 路径 String remoteToFilePath = "hdfs:///user/hadoop/new.txt"; // 设置目标文件的 HDFS 路径
try { // 使用 try-catch 块捕获异常 // 调用 mv 方法移动文件,如果移动成功 if (HDFSApi.mv(conf, remoteFilePath, remoteToFilePath)) { // 输出成功移动文件的提示信息 System.out.println("将文件 " + remoteFilePath + " 移动到 " + remoteToFilePath); } else { // 输出文件移动失败的提示信息 System.out.println("操作失败(源文件不存在或移动失败)"); } } catch (Exception e) { // 捕获可能的异常 e.printStackTrace(); // 打印异常信息 } } }
(二)编程实现一个类“MyFSDataInputStream”,该类继承“org.apache.hadoop.fs.FSDataInputStream”,要求如下:实现按行读取HDFS中指定文件的方法“readLine()”,如果读到文件末尾,则返回空,否则返回文件一行的文本。 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader;
import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FileSystem;
public class MyFSDataInputStream extends FSDataInputStream{
private static MyFSDataInputStream my; private static InputStream inputStream;
public MyFSDataInputStream(InputStream in) { super(in); inputStream = in; }
public static MyFSDataInputStream getInstance(InputStream inputStream){ if (null == my){ synchronized (MyFSDataInputStream.class){ if (null == my){ my = new MyFSDataInputStream(inputStream); } } } return my; }
public static String readline(FileSystem fileStatus) { BufferedReader bfr = new BufferedReader(new InputStreamReader(inputStream)); String line = null; try { if((line=bfr.readLine())!=null) { bfr.close(); inputStream.close(); return line; } } catch (IOException e) { e.printStackTrace(); } return null;
} }
(三)查看Java帮助手册或其它资料,用“java.net.URL”和“org.apache.hadoop.fs.FsURLStreamHandlerFactory”编程完成输出HDFS中指定文件的文本到终端中。 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.util.Scanner;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.FsUrlStreamHandlerFactory; import org.apache.hadoop.fs.Path;
public class last {
private static Path filename; private static FileSystem fs;
public static void main(String[] args) throws IOException { Configuration conf = new Configuration(); conf.set("fs.defaultFS", "hdfs://localhost:9000"); conf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem"); fs = FileSystem.get(conf); System.out.print("输入文件名称: "); Scanner input = new Scanner(System.in); filename = new Path(input.next()); if(!fs.exists(filename)) { System.out.println("文件不存在"); System.exit(1); } show(); }
public static void show() { try { URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory()); InputStream is = new URL("hdfs","localhost",9000,filename.toString()).openStream(); BufferedReader bfr = new BufferedReader(new InputStreamReader(is)); String line = null; while((line = bfr.readLine())!=null) System.out.println(line); }catch(IOException e) { e.printStackTrace(); } }
}
|
||||

浙公网安备 33010602011771号