任务描述
本关任务:使用HDFS的Java接口进行文件的读写,文件uri地址为hdfs://localhost:9000/user/hadoop/task.txt。
相关知识
在本关和之后的关卡中,我们要深入探索Hadoop的FileSystem类,它是与Hadoop的某一文件系统进行交互的API。
为了完成本关任务,你需要学习并掌握:1.FileSystem对象的使用,2.FSDataInputSteam对象的使用。
如果你想要在windows下调试编写Hadoop程序,可以查看这篇帖子:在Windows下开发Hadoop程序
FileSystem对象
要从Hadoop文件系统中读取文件,最简单的办法是使用java.net.URL对象打开数据流,从中获取数据。不过这种方法一般要使用FsUrlStreamHandlerFactory实例调用setURLStreamHandlerFactory()方法。不过每个Java虚拟机只能调用一次这个方法,所以如果其他第三方程序声明了这个对象,那我们将无法使用了。
因为有时候我们不能在程序中设置URLStreamHandlerFactory实例,这个时候咱们就可以使用FileSystem API来打开一个输入流,进而对HDFS进行操作。
FileSystem API 实例
接下来我们通过一个 实例 来学习它的用法。
首先我们在本地创建一个文件,然后上传到HDFS以供测试。
接下来,我们使用FileSystem,查看咱们刚刚上传的文件。
示例代码如下:
public sattic void main(String[] args){ URI uri = URI.create("hdfs://localhost:9000/user/tmp/test.txt"); Configuration config = new Configuration(); FileSystem fs = FileSystem.get(uri, config); InputStream in = null; try { in = fs.open(new Path(uri)); IOUtils.copyBytes(in, System.out, 2048, false); } catch (Exception e) { IOUtils.closeStream(in); } } ———————————————— 版权声明:本文为CSDN博主「真题OK撒」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_51916951/article/details/123585195
你可以直接在右侧命令行与代码文件中测试,点击评测可以查看代码运行效果。运行成功效果如下:
上文中,FileSystem
是一个通用的文件系统API
,FileSystem
实例有下列几个静态工厂方法用来构造对象。
public static FileSystem get(Configuration conf)throws IOException public static FileSystem get(URI uri,Configuration conf)throws IOException public static FileSystem get(URI uri,Configuration conf,String user)throws IOException ———————————————— 版权声明:本文为CSDN博主「真题OK撒」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_51916951/article/details/123585195
Configuration
对象封装了客户端或服务器的配置,通过设置配置文件读取类路径来实现(如:/etc/hadoop/core-site.xml
)。
- 第一个方法返回的默认文件系统是在
core-site.xml
中指定的,如果没有指定,就使用默认的文件系统。 - 第二个方法使用给定的
URI
方案和权限来确定要使用的文件系统,如果给定URI
中没有指定方案,则返回默认文件系统, - 第三个方法作为给定用户来返回文件系统,这个在安全方面来说非常重要。
FSDataInputStream对象
实际上,FileSystem对象中的open()方法返回的就是FSDataInputStream对象,而不是标准的java.io类对象。这个类是继承了java.io.DataInputStream的一个特殊类,并支持随机访问,由此可以从流的任意位置读取数据。
在有了FileSystem实例之后,我们调用open()函数来获取文件的输入流。
public FSDataInputStream open(Path p)throws IOException public abstract FSDataInputStream open(Path f,int bufferSize)throws IOException
第一个方法使用默认的缓冲区大小为4KB。
了解了这些,我们在来回顾上文代码,就能更好的理解这些方法的作用了:
编程要求
在右侧代码编辑区中编写代码实现如下功能:
使用FSDataInputStream获取HDFS的/user/hadoop/目录下的task.txt的文件内容,并输出,其中uri为hdfs://localhost:9000/user/hadoop/task.txt。
测试说明
点击评测,平台会通过脚本创建/user/hadoop/task.txt文件并添加相应内容,无需你自己创建,开启hadoop,编写代码点击评测即可。因为Hadoop环境非常消耗资源,所以你如果一段时间不在线,后台会销毁你的镜像,之前的数据会丢失(你的代码不会丢失),这个时候需要你重新启动Hadoop。
public class FileSystemCat { public static void main(String[] args) throws IOException { URI uri = URI.create("hdfs://localhost:9000/user/hadoop/task.txt"); Configuration config = new Configuration(); FileSystem fs = FileSystem.get(uri, config); InputStream in = null; try { in = fs.open(new Path(uri)); IOUtils.copyBytes(in, System.out, 2048, false); } catch (Exception e) { IOUtils.closeStream(in); } } }
预期输出:
WARN [main] - Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
怕什么真理无穷,进一寸有一寸的欢喜。
第一行打印出来的是log4j的日志警告,可以忽略。
开始你的任务吧,祝你成功!