import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
import java.io.IOException;
public class HShell implements Tool {
public static void main(String[] args) {
// 程序的入口点,使用ToolRunner来运行HShell实例
int res = ToolRunner.run(new Configuration(), new HShell(), args);
// 退出程序,并返回运行结果
System.exit(res);
}
@Override
public int run(String[] args) throws Exception {
// 检查是否提供了足够的参数
if (args.length < 2) {
System.out.println("用法:HShell <命令> [选项] <参数>");
return -1;
}
// 命令行参数中的第一个参数是命令
String command = args[0];
// 剩余的参数是选项和参数,创建一个新的数组来存储它们
String[] options = new String[args.length - 1];
System.arraycopy(args, 1, options, 0, options.length);
// 根据命令执行相应的操作
try {
switch (command) {
case "-cp":
// 拷贝文件命令
if (options.length < 2) {
System.out.println("用法:-cp <本地路径> <HDFS路径>");
return -1;
}
// 调用拷贝文件的方法
copyFile(options[0], options[1]);
break;
case "-rm":
// 删除文件或目录命令
if (options.length < 1) {
System.out.println("用法:-rm [路径]");
return -1;
}
// 检查是否有递归删除目录的选项
if ("-r".equals(options[0])) {
deleteDirectory(options[1]);
} else {
deleteFile(options[0]);
}
break;
case "-cp -r":
// 递归拷贝目录命令
if (options.length < 2) {
System.out.println("用法:-cp -r <本地目录路径> <HDFS路径>");
return -1;
}
// 调用递归拷贝目录的方法
copyDirectory(options[0], options[1]);
break;
case "-list":
// 列出文件或目录信息命令
if (options.length < 1) {
System.out.println("用法:-list <路径>");
return -1;
}
// 调用列出路径信息的方法
listPath(options[0]);
break;
case "-mv":
// 移动或重命名文件命令
if (options.length < 2) {
System.out.println("用法:-mv <源路径> <目标路径>");
return -1;
}
// 调用移动文件的方法
moveFile(options[0], options[1]);
break;
case "-find":
// 递归查找文件命令
if (options.length < 2) {
System.out.println("用法:-find <文件名> <目录>");
return -1;
}
// 调用查找文件的方法
findFile(options[0], options[1]);
break;
default:
// 如果命令未知,则打印错误信息
System.out.println("未知命令:" + command);
return -1;
}
} catch (Exception e) {
// 打印异常堆栈信息,并返回错误代码
e.printStackTrace();
return -1;
}
// 如果没有异常发生,返回成功代码
return 0;
}
// 私有方法,用于实现文件拷贝逻辑
private void copyFile(String localPath, String hdfsPath) throws IOException {
// 创建Hadoop的配置对象
Configuration conf = new Configuration();
// 获取FileSystem对象
FileSystem fs = FileSystem.get(conf);
// 创建本地文件系统和HDFS的输入输出流对象
FSDataInputStream in = null;
FSDataOutputStream out = null;
try {
// 打开本地文件的输入流
in = fs.open(new Path(localPath));
// 打开HDFS文件的输出流
out = fs.create(new Path(hdfsPath));
// 缓冲区用于存储从输入流读取的数据
byte[] buffer = new byte[8192];
int bytesRead;
// 循环读取本地文件并写入到HDFS
while ((bytesRead = in.read(buffer)) > 0) {
out.write(buffer, 0, bytesRead);
}
// 文件拷贝完成,刷新输出流
out.hflush();
} finally {
// 关闭流资源
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
// 关闭FileSystem对象
fs.close();
}
}
// 私有方法,用于实现文件删除逻辑
private void deleteDirectory(String hdfsPath) throws IOException {
// 创建Hadoop的配置对象
Configuration conf = new Configuration();
// 获取FileSystem对象
FileSystem fs = private void deleteFile(String hdfsPath) throws IOException {
// 创建Hadoop的配置对象
Configuration conf = new Configuration();
// 获取FileSystem对象
FileSystem fs = FileSystem.get(conf);
try {
// 检查文件是否存在
if (fs.exists(new Path(hdfsPath))) {
// 删除文件
boolean result = fs.delete(new Path(hdfsPath), false);
if (result) {
System.out.println("文件 " + hdfsPath + " 已成功删除。");
} else {
System.out.println("无法删除文件 " + hdfsPath);
}
} else {
System.out.println("文件 " + hdfsPath + " 不存在。");
}
} finally {
// 关闭FileSystem对象
fs.close();
}
}FileSystem.get(conf);
try {
// 检查目录是否存在
if (fs.exists(new Path(hdfsPath))) {
// 递归删除目录及其所有子目录和文件
boolean result = fs.delete(new Path(hdfsPath), true);
if (result) {
System.out.println("目录 " + hdfsPath + " 及其所有内容已成功删除。");
} else {
System.out.println("无法删除目录 " + hdfsPath);
}
} else {
System.out.println("目录 " + hdfsPath + " 不存在。");
}
} finally {
// 关闭FileSystem对象
fs.close();
}
}
// 私有方法,用于实现目录删除逻辑
private void deleteDirectory(String hdfsPath) throws IOException {
// 创建Hadoop的配置对象
Configuration conf = new Configuration();
// 获取FileSystem对象
FileSystem fs = FileSystem.get(conf);
try {
// 检查目录是否存在
if (fs.exists(new Path(hdfsPath))) {
// 递归删除目录及其所有子目录和文件
boolean result = fs.delete(new Path(hdfsPath), true);
if (result) {
System.out.println("目录 " + hdfsPath + " 及其所有内容已成功删除。");
} else {
System.out.println("无法删除目录 " + hdfsPath);
}
} else {
System.out.println("目录 " + hdfsPath + " 不存在。");
}
} finally {
// 关闭FileSystem对象
fs.close();
}
} private void deleteDirectory(String hdfsPath) throws IOException {
// 这里应该实现使用FileSystem API的目录删除逻辑
}
// 私有方法,用于实现目录拷贝逻辑
private void copyDirectory(String localDirPath, String hdfsPath) throws IOException {
// 创建Hadoop的配置对象
Configuration conf = new Configuration();
// 获取FileSystem对象
FileSystem fs = FileSystem.get(conf);
// 获取本地文件系统
FileSystem localFs = FileSystem.getLocal(conf);
try {
// 检查本地目录是否存在
if (!localFs.exists(new Path(localDirPath))) {
System.out.println("本地目录 " + localDirPath + " 不存在。");
return;
}
// 检查HDFS目标路径是否存在,如果存在且为文件则抛出异常
if (fs.exists(new Path(hdfsPath)) && !fs.isDirectory(new Path(hdfsPath))) {
throw new IOException("目标路径 " + hdfsPath + " 已存在,且是一个文件。");
}
// 递归拷贝目录
FileStatus[] statuses = localFs.listStatus(new Path(localDirPath));
for (FileStatus status : statuses) {
Path localPath = status.getPath();
Path hdfsTargetPath = new Path(hdfsPath, localPath.toUri().relativize(localPath.toUri().getPath()));
if (status.isDirectory()) {
// 创建HDFS目录
fs.mkdirs(hdfsTargetPath);
} else {
// 拷贝文件内容
InputStream in = null;
OutputStream out = null;
try {
in = localFs.open(localPath);
out = fs.create(hdfsTargetPath);
IOUtils.copyBytes(in, out, conf);
} finally {
IOUtils.closeStream(in);
IOUtils.closeStream(out);
}
}
}
} finally {
// 关闭FileSystem对象
fs.close();
localFs.close();
}
}
// 私有方法,用于实现列出文件或目录信息的逻辑
private void listPath(String hdfsPath) throws IOException {
// 创建Hadoop的配置对象
Configuration conf = new Configuration();
// 获取FileSystem对象
FileSystem fs = FileSystem.get(conf);
try {
// 检查指定路径是否存在
if (!fs.exists(new Path(hdfsPath))) {
System.out.println("指定的路径 " + hdfsPath + " 不存在。");
return;
}
// 获取指定路径下的文件和目录信息
FileStatus[] fileStatuses = fs.listStatus(new Path(hdfsPath));
// 遍历FileStatus数组并打印信息
for (FileStatus fileStatus : fileStatuses) {
String output = StringUtils.format("- " + fileStatus.getPath() + " " + fileStatus.getLen() + " bytes");
System.out.println(output);
}
} finally {
// 关闭FileSystem对象
fs.close();
}
}
// 私有方法,用于实现文件移动或重命名逻辑
private void moveFile(String srcPath, String destPath) throws IOException {
// 创建Hadoop的配置对象
Configuration conf = new Configuration();
// 获取FileSystem对象
FileSystem fs = FileSystem.get(conf);
try {
// 检查源文件是否存在
if (!fs.exists(new Path(srcPath))) {
System.out.println("源文件 " + srcPath + " 不存在。");
return;
}
// 尝试移动文件到目标路径
boolean result = fs.rename(new Path(srcPath), new Path(destPath));
if (result) {
System.out.println("文件 " + srcPath + " 已成功移动到 " + destPath + "。");
} else {
System.out.println("无法移动文件 " + srcPath + " 到 " + destPath + "。");
}
} finally {
// 关闭FileSystem对象
fs.close();
}
}
private void findFile(String fileName, String directory) throws IOException {
// 创建Hadoop的配置对象
Configuration conf = new Configuration();
// 获取FileSystem对象
FileSystem fs = FileSystem.get(conf);
try {
// 构建要查找的文件的Path对象
Path targetPath = new Path(directory, fileName);
// 获取目录列表
FileStatus[] listStatus = fs.listStatus(targetPath);
// 遍历目录列表,查找匹配的文件
for (FileStatus fileStatus : listStatus) {
Path currentPath = fileStatus.getPath();
// 如果找到文件且文件名匹配,则输出文件路径
if (currentPath.getName().equals(fileName) && !fileStatus.isDirectory()) {
System.out.println("找到文件: " + currentPath);
}
// 如果当前路径是目录,则递归查找该目录下匹配的文件
else if (fileStatus.isDirectory()) {
findFile(fileName, currentPath.toString());
}
}
} finally {
// 关闭FileSystem对象
fs.close();
}
}
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
import java.io.IOException;
public class HShell implements Tool {
public static void main(String[] args) {
// 程序的入口点,使用ToolRunner来运行HShell实例
int res = ToolRunner.run(new Configuration(), new HShell(), args);
// 退出程序,并返回运行结果
System.exit(res);
}
@Override
public int run(String[] args) throws Exception {
// 检查是否提供了足够的参数
if (args.length < 2) {
System.out.println("用法:HShell <命令> [选项] <参数>");
return -1;
}
// 命令行参数中的第一个参数是命令
String command = args[0];
// 剩余的参数是选项和参数,创建一个新的数组来存储它们
String[] options = new String[args.length - 1];
System.arraycopy(args, 1, options, 0, options.length);
// 根据命令执行相应的操作
try {
switch (command) {
case "-cp":
// 拷贝文件命令
if (options.length < 2) {
System.out.println("用法:-cp <本地路径> <HDFS路径>");
return -1;
}
// 调用拷贝文件的方法
copyFile(options[0], options[1]);
break;
case "-rm":
// 删除文件或目录命令
if (options.length < 1) {
System.out.println("用法:-rm [路径]");
return -1;
}
// 检查是否有递归删除目录的选项
if ("-r".equals(options[0])) {
deleteDirectory(options[1]);
} else {
deleteFile(options[0]);
}
break;
case "-cp -r":
// 递归拷贝目录命令
if (options.length < 2) {
System.out.println("用法:-cp -r <本地目录路径> <HDFS路径>");
return -1;
}
// 调用递归拷贝目录的方法
copyDirectory(options[0], options[1]);
break;
case "-list":
// 列出文件或目录信息命令
if (options.length < 1) {
System.out.println("用法:-list <路径>");
return -1;
}
// 调用列出路径信息的方法
listPath(options[0]);
break;
case "-mv":
// 移动或重命名文件命令
if (options.length < 2) {
System.out.println("用法:-mv <源路径> <目标路径>");
return -1;
}
// 调用移动文件的方法
moveFile(options[0], options[1]);
break;
case "-find":
// 递归查找文件命令
if (options.length < 2) {
System.out.println("用法:-find <文件名> <目录>");
return -1;
}
// 调用查找文件的方法
findFile(options[0], options[1]);
break;
default:
// 如果命令未知,则打印错误信息
System.out.println("未知命令:" + command);
return -1;
}
} catch (Exception e) {
// 打印异常堆栈信息,并返回错误代码
e.printStackTrace();
return -1;
}
// 如果没有异常发生,返回成功代码
return 0;
}
// 私有方法,用于实现文件拷贝逻辑
private void copyFile(String localPath, String hdfsPath) throws IOException {
// 创建Hadoop的配置对象
Configuration conf = new Configuration();
// 获取FileSystem对象
FileSystem fs = FileSystem.get(conf);
// 创建本地文件系统和HDFS的输入输出流对象
FSDataInputStream in = null;
FSDataOutputStream out = null;
try {
// 打开本地文件的输入流
in = fs.open(new Path(localPath));
// 打开HDFS文件的输出流
out = fs.create(new Path(hdfsPath));
// 缓冲区用于存储从输入流读取的数据
byte[] buffer = new byte[8192];
int bytesRead;
// 循环读取本地文件并写入到HDFS
while ((bytesRead = in.read(buffer)) > 0) {
out.write(buffer, 0, bytesRead);
}
// 文件拷贝完成,刷新输出流
out.hflush();
} finally {
// 关闭流资源
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
// 关闭FileSystem对象
fs.close();
}
}
// 私有方法,用于实现文件删除逻辑
private void deleteDirectory(String hdfsPath) throws IOException {
// 创建Hadoop的配置对象
Configuration conf = new Configuration();
// 获取FileSystem对象
FileSystem fs = private void deleteFile(String hdfsPath) throws IOException {
// 创建Hadoop的配置对象
Configuration conf = new Configuration();
// 获取FileSystem对象
FileSystem fs = FileSystem.get(conf);
try {
// 检查文件是否存在
if (fs.exists(new Path(hdfsPath))) {
// 删除文件
boolean result = fs.delete(new Path(hdfsPath), false);
if (result) {
System.out.println("文件 " + hdfsPath + " 已成功删除。");
} else {
System.out.println("无法删除文件 " + hdfsPath);
}
} else {
System.out.println("文件 " + hdfsPath + " 不存在。");
}
} finally {
// 关闭FileSystem对象
fs.close();
}
}FileSystem.get(conf);
try {
// 检查目录是否存在
if (fs.exists(new Path(hdfsPath))) {
// 递归删除目录及其所有子目录和文件
boolean result = fs.delete(new Path(hdfsPath), true);
if (result) {
System.out.println("目录 " + hdfsPath + " 及其所有内容已成功删除。");
} else {
System.out.println("无法删除目录 " + hdfsPath);
}
} else {
System.out.println("目录 " + hdfsPath + " 不存在。");
}
} finally {
// 关闭FileSystem对象
fs.close();
}
}
// 私有方法,用于实现目录删除逻辑
private void deleteDirectory(String hdfsPath) throws IOException {
// 创建Hadoop的配置对象
Configuration conf = new Configuration();
// 获取FileSystem对象
FileSystem fs = FileSystem.get(conf);
try {
// 检查目录是否存在
if (fs.exists(new Path(hdfsPath))) {
// 递归删除目录及其所有子目录和文件
boolean result = fs.delete(new Path(hdfsPath), true);
if (result) {
System.out.println("目录 " + hdfsPath + " 及其所有内容已成功删除。");
} else {
System.out.println("无法删除目录 " + hdfsPath);
}
} else {
System.out.println("目录 " + hdfsPath + " 不存在。");
}
} finally {
// 关闭FileSystem对象
fs.close();
}
} private void deleteDirectory(String hdfsPath) throws IOException {
// 这里应该实现使用FileSystem API的目录删除逻辑
}
// 私有方法,用于实现目录拷贝逻辑
private void copyDirectory(String localDirPath, String hdfsPath) throws IOException {
// 创建Hadoop的配置对象
Configuration conf = new Configuration();
// 获取FileSystem对象
FileSystem fs = FileSystem.get(conf);
// 获取本地文件系统
FileSystem localFs = FileSystem.getLocal(conf);
try {
// 检查本地目录是否存在
if (!localFs.exists(new Path(localDirPath))) {
System.out.println("本地目录 " + localDirPath + " 不存在。");
return;
}
// 检查HDFS目标路径是否存在,如果存在且为文件则抛出异常
if (fs.exists(new Path(hdfsPath)) && !fs.isDirectory(new Path(hdfsPath))) {
throw new IOException("目标路径 " + hdfsPath + " 已存在,且是一个文件。");
}
// 递归拷贝目录
FileStatus[] statuses = localFs.listStatus(new Path(localDirPath));
for (FileStatus status : statuses) {
Path localPath = status.getPath();
Path hdfsTargetPath = new Path(hdfsPath, localPath.toUri().relativize(localPath.toUri().getPath()));
if (status.isDirectory()) {
// 创建HDFS目录
fs.mkdirs(hdfsTargetPath);
} else {
// 拷贝文件内容
InputStream in = null;
OutputStream out = null;
try {
in = localFs.open(localPath);
out = fs.create(hdfsTargetPath);
IOUtils.copyBytes(in, out, conf);
} finally {
IOUtils.closeStream(in);
IOUtils.closeStream(out);
}
}
}
} finally {
// 关闭FileSystem对象
fs.close();
localFs.close();
}
}
// 私有方法,用于实现列出文件或目录信息的逻辑
private void listPath(String hdfsPath) throws IOException {
// 创建Hadoop的配置对象
Configuration conf = new Configuration();
// 获取FileSystem对象
FileSystem fs = FileSystem.get(conf);
try {
// 检查指定路径是否存在
if (!fs.exists(new Path(hdfsPath))) {
System.out.println("指定的路径 " + hdfsPath + " 不存在。");
return;
}
// 获取指定路径下的文件和目录信息
FileStatus[] fileStatuses = fs.listStatus(new Path(hdfsPath));
// 遍历FileStatus数组并打印信息
for (FileStatus fileStatus : fileStatuses) {
String output = StringUtils.format("- " + fileStatus.getPath() + " " + fileStatus.getLen() + " bytes");
System.out.println(output);
}
} finally {
// 关闭FileSystem对象
fs.close();
}
}
// 私有方法,用于实现文件移动或重命名逻辑
private void moveFile(String srcPath, String destPath) throws IOException {
// 创建Hadoop的配置对象
Configuration conf = new Configuration();
// 获取FileSystem对象
FileSystem fs = FileSystem.get(conf);
try {
// 检查源文件是否存在
if (!fs.exists(new Path(srcPath))) {
System.out.println("源文件 " + srcPath + " 不存在。");
return;
}
// 尝试移动文件到目标路径
boolean result = fs.rename(new Path(srcPath), new Path(destPath));
if (result) {
System.out.println("文件 " + srcPath + " 已成功移动到 " + destPath + "。");
} else {
System.out.println("无法移动文件 " + srcPath + " 到 " + destPath + "。");
}
} finally {
// 关闭FileSystem对象
fs.close();
}
}
// 私有方法,用于实现递归查找文件的逻辑
private void moveFile(String srcPath, String destPath) throws IOException {
// 创建Hadoop的配置对象
Configuration conf = new Configuration();
// 获取FileSystem对象
FileSystem fs = FileSystem.get(conf);
try {
// 构建源文件和目标文件的Path对象
Path src = new Path(srcPath);
Path dest = new Path(destPath);
// 检查源文件是否存在
if (!fs.exists(src)) {
System.out.println("源文件 " + srcPath + " 不存在。");
return;
}
// 尝试移动文件到目标路径
if (fs.rename(src, dest)) {
System.out.println("文件已成功从 " + srcPath + " 移动到 " + destPath + "。");
} else {
System.out.println("移动文件失败,文件可能已被移动或删除。");
throw new IOException("无法移动文件从 " + srcPath + " 到 " + destPath + "。");
}
} finally {
// 关闭FileSystem对象
fs.close();
}
}