Hadoop有一个抽象文件系统的概念,hdfs只是其中的一个实现,Java抽象类org.apache.hadoop.fs.FileSystem定义了hadoop中的一个文件系统接口,hdfs是实现了这个接口的一个文件系统,还有其它的文件系统实现,例如使用了本地磁盘文件系统的Local文件系统和RawLocalFilesystem等。
一:hdfs命令行接口
类似于传统的文件系统,hdfs提供命令行接口来操作文件系统。Hdfs的命令形式一般为:%hadoop fs -ls /temp。其中hadoop表示调用hadoop命令,fs表示hadoop中的文件系统,-ls是hdfs中的一个命令,都需要一个”-”在文件系统命令前面,再后面为命令的参数。示例命令的含义为查看hdfs中/temp目录下的所有文件信息。
二:Java接口
编写java程序访问hdfs文件系统有两种方式,一种是通过URL读取数据,另一种是通过Hadoop的Filesystem API来访问文件系统。
- 从Hadoop URL读取数据
一种最简单的从HDFS读取数据的方式是通过java.net.URL类来打开一个输入流,通过读取流来读取数据。要使java程序识别hadoop的URL方案,需要特殊的设置。Hadoop的解决方案是调用java.net.URL的setURLStreamHandlerFactory方法,设置一个FsUrlStreamHandlerFactory来识别hdfs的文件URL方案。另外,Hadoop提供了一个IOUtils类来处理流等。在一个java虚拟机中,setURLStreamHandlerFactory方法只允许调用一次,因此如果同一个虚拟机中的第三方组件使用了同一个方法,这个就不能使用了。
- 通过API访问数据
当无法使用setURLStreamHandlerFactory方法时,只有使用hadoop提供的FileSystem API来访问hdfs。FileSystem提供get方法来获取一个文件系统的实例,具体获取的文件系统由一个配置类configuration的对象来决定,这个对象的内容是有配置文件中的内容决定的,具体来说就是core-site.xml决定的。同时get方法还可以有两个参数,URI与user,前者代表URI方案,也可以指定文件系统实例,后者代表用户。获取文件系统实例后,可以打开文件获取FSDataInputStream,这个流继承了java.io.DataInputStream,同时实现了两个接口,使其可以读取文件的特定位置的内容,获取现在所在位置想对于文件起点的偏移量等随机读取功能。
Hdfs写入文件可以使用create或者append获取一个FSDataOutputStream对象,这个对象可以用来在文件末尾追加数据。Hadoop不支持随机的文件写操作。同时API提供了新建文件夹的操作。Filestatus用来保存文件信息,同时FileSystemAPI 提供listStatus方法来列出一个目录下所有的文件的信息。提供delete方法来删除文件或者目录。
- 通配符与PathFilter
处理一系列文件是非常常见的需求,有时候需要从一系列文件中选择符合特定条件的文件作为输入,此时可以使用通配符来实现只处理一部分文件的功能。但是通配符不一定满足需求,此时可以利用PathFilter来进一步优化实现更复杂的过滤需求。