提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
由于Hadoop是使用Java语言编写的,因此可以使用Java API操作Hadoop文件系统。HDFS Shell本质上就是对Java API的应用,通过编程的形式操作HDFS,其核心是使用HDFS提供的Java API构造一个访问客户端对象,然后通过客户端对象对HDFS上的文件进行操作(增、删、改、查)。
org.apache.hadoop hadoop-client 3.3.4 junit junit 4.13.2
package net.at.hdfs;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.Test;
import java.net.URI;
/*** 功能:在HDFS上创建文件* 作者:Argonaut* 日期:2022年11月30日*/
public class CreateFileOnHDFS {@Testpublic void create1() throws Exception {// 创建配置对象Configuration conf = new Configuration();// 定义统一资源标识符(uri: uniform resource identifier)String uri = "hdfs://master:9000";// 创建文件系统对象(基于HDFS的文件系统)FileSystem fs = FileSystem.get(new URI(uri), conf);// 创建路径对象(指向文件)Path path = new Path(uri + "/ied01/hadoop.txt");// 基于路径对象创建文件boolean result = fs.createNewFile(path);// 根据返回值判断文件是否创建成功if (result) {System.out.println("文件[" + path + "]创建成功!");} else {System.out.println("文件[" + path + "]创建失败!");}}
}
@Test
public void create2() throws Exception { // 创建配置对象 Configuration conf = new Configuration(); // 定义统一资源标识符(uri:uniform resource identifier) String uri = "hdfs://master:9000"; // 创建文件系统对象(基于HDFS的文件系统) FileSystem fs = FileSystem.get(new URI(uri), conf); // 创建路径对象 Path path = new Path(uri + "/ied01/hadoop.txt"); // 判断路径对象指向的文件是否存在 if (fs.exists(path)) { // 提示用户文件已存在 System.out.println("文件[" + path + "]已经存在!"); } else { // 基于路径对象创建文件 boolean result = fs.createNewFile(path); // 根据返回值判断文件是否创建成功 if (result) { System.out.println("文件[" + path + "]创建成功!"); } else { System.out.println("文件[" + path + "]创建失败!"); } }
}
@Test
public void create2() throws Exception { // 创建配置对象 Configuration conf = new Configuration(); // 定义统一资源标识符(uri: uniform resource identifier) String uri = "hdfs://master:9000"; // 创建文件系统对象(基于HDFS的文件系统) FileSystem fs = FileSystem.get(new URI(uri), conf); // 创建路径对象(指向文件) Path path = new Path(uri + "/ied01/hadoop.txt"); // 判断路径对象指向的文件是否存在 if (fs.exists(path)) { // 提示用户文件已存在 System.out.println("文件[" + path + "]已经存在!"); } else { try { // 基于路径对象创建文件 boolean result = fs.createNewFile(path); // 根据返回值判断文件是否创建成功 if (result) { System.out.println("文件[" + path + "]创建成功!"); } else { System.out.println("文件[" + path + "]创建失败!"); } } catch (Exception e) { System.err.println("异常信息:" + e.getMessage()); } }
}
package net.at.hdfs;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.Test;import java.net.URI;/*** 功能:写入HDFS文件* 作者:Argonaut* 日期:2022年11月30日*/
public class WriteFileOnHDFS {@Testpublic void write1() throws Exception {// 创建配置对象Configuration conf = new Configuration();// 定义统一资源标识符(uri: uniform resource identifier)String uri = "hdfs://master:9000";// 创建文件系统对象(基于HDFS的文件系统)FileSystem fs = FileSystem.get(new URI(uri), conf);// 创建路径对象(指向文件)Path path = new Path(uri + "/ied01/hello.txt");// 创建文件系统数据字节输出流(出水管:数据从程序到文件)FSDataOutputStream out = fs.create(path);// 通过字节输出流向文件写数据out.write("Hello Hadoop World".getBytes());// 关闭文件系统数据字节输出流out.close();// 关闭文件系统对象fs.close();// 提示用户写文件成功System.out.println("文件[" + path + "]写入成功!");}
}
@Test
public void write2() throws Exception { // 创建配置对象 Configuration conf = new Configuration(); // 设置数据节点主机名属性 conf.set("dfs.client.use.datanode.hostname", "true"); // 定义统一资源标识符(uri: uniform resource identifier) String uri = "hdfs://master:9000"; // 创建文件系统对象(基于HDFS的文件系统) FileSystem fs = FileSystem.get(new URI(uri), conf, "root"); // 创建路径对象(指向文件) Path path = new Path(uri + "/ied01/exam.txt"); // 创建文件系统数据字节输出流(出水管:数据从程序到文件) FSDataOutputStream out = fs.create(path); // 创建文件字符输入流对象(进水管:数据从文件到程序) FileReader fr = new FileReader("test.txt"); // 创建缓冲字符输入流对象 BufferedReader br = new BufferedReader(fr); // 定义行字符串变量 String nextLine = ""; // 通过循环遍历缓冲字符输入流 while ((nextLine = br.readLine()) != null) { // 在控制台输出读取的行 System.out.println(nextLine); // 通过文件系统数据字节输出流对象写入指定文件 out.write((nextLine + "\n").getBytes()); } // 关闭缓冲字符输入流 br.close(); // 关闭文件字符输入流 fr.close(); // 关闭文件系统数据字节输出流 out.close(); // 提示用户写入文件成功 System.out.println("本地文件[test.txt]成功写入[" + path + "]!");
}
@Test
public void write2_() throws Exception { // 创建配置对象 Configuration conf = new Configuration(); // 设置数据节点主机名属性 conf.set("dfs.client.use.datanode.hostname", "true"); // 定义统一资源标识符(uri: uniform resource identifier) String uri = "hdfs://master:9000"; // 创建文件系统对象(基于HDFS的文件系统) FileSystem fs = FileSystem.get(new URI(uri), conf, "root"); // 创建路径对象(指向文件) Path path = new Path(uri + "/ied01/test.txt"); // 创建文件系统数据字节输出流(出水管:数据从程序到文件) FSDataOutputStream out = fs.create(path); // 创建文件字节输入流(进水管:数据从文件到程序) FileInputStream in = new FileInputStream("test.txt"); // 利用IOUtils类提供的字节拷贝方法在控制台显示文件内容 IOUtils.copyBytes(in, System.out, 1024, false); // 利用IOUtils类提供的字节拷贝方法来复制文件 IOUtils.copyBytes(in, out, conf); // 关闭文件字节输入流 in.close(); // 关闭文件系统数据字节输出流 out.close(); // 提示用户写入文件成功 System.out.println("本地文件[test.txt]成功写入[" + path + "]!");
}
package net.at.hdfs;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.Test;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;/*** 功能:读取HDFS文件* 作者:Argonaut* 日期:2022年11月30日*/
public class ReadFileOnHDFS {@Testpublic void read1() throws Exception {// 创建配置对象Configuration conf = new Configuration();// 设置数据节点主机名属性conf.set("dfs.client.use.datanode.hostname", "true");// 定义统一资源标识符(uri: uniform resource identifier)String uri = "hdfs://master:9000";// 创建文件系统对象(基于HDFS的文件系统)FileSystem fs = FileSystem.get(new URI(uri), conf, "root");// 创建路径对象(指向文件)Path path = new Path(uri + "/ied01/test.txt");// 创建文件系统数据字节输入流(进水管:数据从文件到程序)FSDataInputStream in = fs.open(path);// 创建缓冲字符输入流,提高读取效率(字节流-->字符流-->缓冲流)BufferedReader br = new BufferedReader(new InputStreamReader(in));// 定义行字符串变量String nextLine = "";// 通过循环遍历缓冲字符输入流while ((nextLine = br.readLine()) != null) {// 在控制台输出读取的行System.out.println(nextLine);}// 关闭缓冲字符输入流br.close();// 关闭文件系统数据字节输入流in.close();// 关闭文件系统fs.close();}
}
@Test
public void read2() throws Exception { // 创建配置对象 Configuration conf = new Configuration(); // 设置数据节点主机名属性 conf.set("dfs.client.use.datanode.hostname", "true"); // 定义统一资源标识符(uri: uniform resource identifier) String uri = "hdfs://master:9000"; // 创建文件系统对象(基于HDFS的文件系统) FileSystem fs = FileSystem.get(new URI(uri), conf, "root"); // 创建路径对象(指向文件) Path path = new Path(uri + "/ied01/test.txt"); // 创建文件系统数据字节输入流(进水管:数据从文件到程序) FSDataInputStream in = fs.open(path); // 创建文件字节输出流(出水管:数据从程序到文件) FileOutputStream out = new FileOutputStream("download/exam.txt"); // 利用IOUtils工具类读取HDFS文件(靠输入流),写入本地文件(靠输出流) IOUtils.copyBytes(in, out, conf); // 关闭文件字节输出流 out.close(); // 关闭文件系统数据字节流输入流 in.close(); // 关闭文件系统 fs.close(); // 提示用户文件下载成功 System.out.println("文件[" + path + "]下载到本地文件[download/exam.txt]!");
}
package net.at.hdfs;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;
import org.junit.Test;import java.net.URI;/*** 功能:显示文件列表* 作者:Argonaut* 日期:2022年11月26日*/
public class ListHDFSFiles {@Testpublic void list1() throws Exception {// 创建配置对象Configuration conf = new Configuration();// 设置数据节点主机名属性conf.set("dfs.client.use.datanode.hostname", "true");// 定义uri字符串String uri = "hdfs://master:9000";// 创建文件系统对象FileSystem fs = FileSystem.get(new URI(uri), conf, "root");// 创建远程迭代器对象,泛型是位置文件状态类(相当于`hdfs dfs -ls -R /lzy01`)RemoteIterator ri = fs.listFiles(new Path("/lzy01"), true);// 遍历远程迭代器while (ri.hasNext()) {System.out.println(ri.next());}}
}
(2)显示指定目录下文件路径和长度信息
package net.at.hdfs;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.BlockLocation;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;import java.net.URI;
import java.util.Arrays;/*** 功能:获取文件块信息* 作者:Argonaut* 日期:2022年11月26日*/
public class GetBlockLocations {public static void main(String[] args) throws Exception {// 创建配置对象Configuration conf = new Configuration();// 设置数据节点主机名属性conf.set("dfs.client.use.datanode.hostname", "true");// 定义uri字符串String uri = "hdfs://master:9000";// 创建文件系统对象FileSystem fs = FileSystem.get(new URI(uri), conf, "root");// 创建路径对象,指向文件Path path = new Path("/lzy01/hadoop-3.3.4.tar.gz");// 获取文件块信息BlockLocation[] blks = fs.getFileBlockLocations(path, 0, Integer.MAX_VALUE);// 利用Lambda表达式遍历块信息Arrays.asList(blks).forEach(blk -> System.out.println(blk));}
}
// 利用增强for循环遍历块信息
for (BlockLocation blk : blks) { System.out.println(blk);
} // 利用传统for循环遍历块信息
for (int i = 0; i < blks.length; i++) { System.out.println(blks[i]);
} // 利用迭代器遍历块信息
Iterator iterator = Arrays.asList(blks).iterator();
while (iterator.hasNext()) { System.out.println(iterator.next());
}
package net.at.hdfs;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;import java.net.URI;/*** 功能:在HDFS上创建目录* 作者:Argonaut* 日期:2022年11月26日*/
public class MakeDirOnHDFS {public static void main(String[] args) throws Exception {// 创建配置对象Configuration conf = new Configuration();// 设置数据节点主机名属性conf.set("dfs.client.use.datanode.hostname", "true");// 定义uri字符串String uri = "hdfs://master:9000";// 创建文件系统对象FileSystem fs = FileSystem.get(new URI(uri), conf, "root");// 创建路径对象,指向目录Path path = new Path("/ied01");// 利用文件系统创建指定目录boolean result = fs.mkdirs(path);// 判断目录是否创建成功if (result) {System.out.println("目录[" + path + "]创建成功!" );} else {System.out.println("目录[" + path + "]创建失败!" );}}
}
package net.at.hdfs;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.Test;import java.net.URI;/*** 功能:判断目录或文件是否存在* 作者:Argonaut* 日期:2022年11月26日*/
public class DirFileExistsOrNot {@Testpublic void dirExists() throws Exception {// 创建配置对象Configuration conf = new Configuration();// 设置数据节点主机名属性conf.set("dfs.client.use.datanode.hostname", "true");// 定义uri字符串String uri = "hdfs://master:9000";// 创建文件系统对象FileSystem fs = FileSystem.get(new URI(uri), conf, "root");// 创建路径对象,指向目录Path path = new Path("/ied01");// 判断目录是否存在if (fs.exists(path)) {System.out.println("目录[" + path + "]存在!");} else {System.out.println("目录[" + path + "]不存在!");}}
}
package net.at.hdfs;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;import java.net.URI;/*** 功能:判断路径指向目录还是文件* 作者:Argonaut* 日期:2022年11月26日*/
public class PathToFileOrDir {public static void main(String[] args) throws Exception {// 创建配置对象Configuration conf = new Configuration();// 设置数据节点主机名属性conf.set("dfs.client.use.datanode.hostname", "true");// 定义uri字符串String uri = "hdfs://master:9000";// 创建文件系统对象FileSystem fs = FileSystem.get(new URI(uri), conf, "root");// 创建路径对象,指向目录Path path1 = new Path("/ied08");if (fs.isDirectory(path1)) {System.out.println("[" + path1 + "]指向的是目录!");} else {System.out.println("[" + path1 + "]指向的是文件!");}// 创建路径对象,指向文件Path path2 = new Path("/lzy01/howard.txt");if (fs.isFile(path2)) {System.out.println("[" + path2 + "]指向的是文件!");} else {System.out.println("[" + path2 + "]指向的是目录!");}}
}
package net.at.hdfs;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.Test;import java.net.URI;/*** 功能:删除目录或文件* 作者:Argonaut* 日期:2022年12月02日*/
public class DeleteFileOrDir {@Testpublic void deleteFile() throws Exception {// 创建配置对象Configuration conf = new Configuration();// 设置数据节点主机名属性conf.set("dfs.client.use.datanode.hostname", "true");// 定义uri字符串String uri = "hdfs://master:9000";// 创建文件系统对象FileSystem fs = FileSystem.get(new URI(uri), conf, "root");// 创建路径对象(指向文件)Path path = new Path(uri + "/lzy01/hi.txt");// 删除路径对象指向的文件(第二个参数表明是否递归,删除文件,不用递归)boolean result = fs.delete(path, false);// 根据返回结果提示用户if (result) {System.out.println("文件[" + path + "]删除成功!");} else {System.out.println("文件[" + path + "]删除失败!");}}
}
@Test
public void deleteDir() throws Exception { // 创建配置对象 Configuration conf = new Configuration(); // 设置数据节点主机名属性 conf.set("dfs.client.use.datanode.hostname", "true"); // 定义uri字符串 String uri = "hdfs://master:9000"; // 创建文件系统对象 FileSystem fs = FileSystem.get(new URI(uri), conf, "root"); // 创建路径对象(指向目录) Path path = new Path(uri + "/lzy01"); // 判断路径对象指向的目录否存在 if (fs.exists(path)) { // 删除路径对象指向的目录(第二个参数表明是否递归,删除文件,要递归) boolean result = fs.delete(path, true); // 根据返回结果提示用户 if (result) { System.out.println("目录[" + path + "]删除成功!"); } else { System.out.println("目录[" + path + "]删除失败!"); } } else { System.out.println("目录[" + path + "]不存在!"); }
}
(3)删除目录或文件
@Test
public void delete() throws Exception { // 创建配置对象 Configuration conf = new Configuration(); // 设置数据节点主机名属性 conf.set("dfs.client.use.datanode.hostname", "true"); // 定义uri字符串 String uri = "hdfs://master:9000"; // 创建文件系统对象 FileSystem fs = FileSystem.get(new URI(uri), conf, "root"); // 定义随机对象 Random random = new Random(); // 产生随机整数 - [0, 1] int choice = random.nextInt(100) % 2; // 定义路径字符串 String[] strPath = {"/ied02/exam.txt", "/lzy01"}; // 创建路径对象(指向目录或文件) Path path = new Path(uri + strPath[choice]); // 判断存在性 if (fs.exists(path)) { // 判断类型:目录或文件 String type = ""; if (fs.isDirectory(path)) { type = "目录"; } else { type = "文件"; } // 删除路径对象指向的目录或文件 boolean result = fs.delete(path, true); // 判断删除是否成功 if (result) { System.out.println(type + "[" + path + "]删除成功!"); } else { System.out.println(type + "[" + path + "]删除失败!"); } } else { System.out.println("路径[" + path + "]不存在!"); }
}