利用API写入文件
写入HDFS文件
- 类似于HDFS Shell里的
hdfs dfs -put
命令 - 在
net.zwh.hdfs
包里创建WriteFileOnHDFS
类
(1)将数据直接写入HDFS文件
- 在
/ied01
目录里创建hello.txt
文件 - 创建
write1()
方法
packagenet.hw.hdfs;importorg.apache.hadoop.conf.Configuration;importorg.apache.hadoop.fs.FSDataOutputStream;importorg.apache.hadoop.fs.FileSystem;importorg.apache.hadoop.fs.Path;importorg.junit.Test;importjava.net.URI;/**
* 功能:写入HDFS文件
*/publicclassWriteFileOnHDFS{@Testpublicvoidwrite1()throwsException{// 创建配置对象Configuration conf =newConfiguration();// 定义统一资源标识符(uri: uniform resource identifier)String uri ="hdfs://master:9000";// 创建文件系统对象(基于HDFS的文件系统)FileSystem fs =FileSystem.get(newURI(uri), conf);// 创建路径对象(指向文件)Path path =newPath(uri +"/ied01/hello.txt");// 创建文件系统数据字节输出流(出水管:数据从程序到文件)FSDataOutputStream out = fs.create(path);// 通过字节输出流向文件写数据
out.write("Hello Hadoop World".getBytes());// 关闭文件系统数据字节输出流
out.close();// 关闭文件系统对象
fs.close();// 提示用户写文件成功System.out.println("文件["+ path +"]写入成功!");}}
- 运行
write1()
测试方法,查看结果,抛出RemoteException
异常,三个数据节点都在运行,但是无法写入数据 - 修改代码,设置数据节点主机名属性,如下图所示
- 运行程序,查看结果
- 利用Hadoop WebUI查看
hello.txt
文件
(2)将本地文件写入HDFS文件
- 在项目根目录创建一个文本文件
test.txt
- 创建write2()方法
@Testpublicvoidwrite2()throwsException{// 创建配置对象 Configuration conf =newConfiguration();// 设置数据节点主机名属性
conf.set("dfs.client.use.datanode.hostname","true");// 定义统一资源标识符(uri: uniform resource identifier) String uri ="hdfs://master:9000";// 创建文件系统对象(基于HDFS的文件系统) FileSystem fs =FileSystem.get(newURI(uri), conf,"root");// 创建路径对象(指向文件) Path path =newPath(uri +"/ied01/exam.txt");// 创建文件系统数据字节输出流(出水管:数据从程序到文件) FSDataOutputStream out = fs.create(path);// 创建文件字符输入流对象(进水管:数据从文件到程序) FileReader fr =newFileReader("test.txt");// 创建缓冲字符输入流对象 BufferedReader br =newBufferedReader(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 +"]!");}
- 运行
write2()
测试方法,查看结果
- 查看
/ied01/exam.txt
内容 - 其实这个方法的功能就是将本地文件复制(上传)到HDFS,有没有更简单的处理方法呢?有的,通过使用一个工具类
IOUtils
来完成文件的相关操作。
- 编写write2_()方法
@Testpublicvoidwrite2_()throwsException{// 创建配置对象 Configuration conf =newConfiguration();// 设置数据节点主机名属性
conf.set("dfs.client.use.datanode.hostname","true");// 定义统一资源标识符(uri: uniform resource identifier) String uri ="hdfs://master:9000";// 创建文件系统对象(基于HDFS的文件系统) FileSystem fs =FileSystem.get(newURI(uri), conf,"root");// 创建路径对象(指向文件) Path path =newPath(uri +"/ied01/test.txt");// 创建文件系统数据字节输出流(出水管:数据从程序到文件) FSDataOutputStream out = fs.create(path);// 创建文件字节输入流(进水管:数据从文件到程序) FileInputStream in =newFileInputStream("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 +"]!");}
注意导包问题
- 运行
write2_()
测试方法,查看结果
- 查看
/ied01/test.txt
内容,文件是存在的,但是没有内容
因为字节输入流的数据已经输出到到控制台,此时字节输入流里已经没有数据,此时执行
IOUtils.copyBytes(in, out, conf)
;,因此输出流肯定也没有数据可以写入文件,那该怎么办呢?再次读取文件,让字节输入流有数据。
- 运行
write2_()
方法,查看结果 - 查看
/ied01/test.txt
文件
本文转载自: https://blog.csdn.net/zl202111/article/details/128311221
版权归原作者 zl202111 所有, 如有侵权,请联系我们删除。
版权归原作者 zl202111 所有, 如有侵权,请联系我们删除。