【HDFS读写路径详解】
HDFS中我们通常使用FileSystem类来操作文件系统,提供了众多类POSIX接口调用风格的方法。一段典型的代码样例为:
public static void read(String path) throws Exception{
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
BufferedReader reader = null;
try{
FSDataInputStream fsInput = fs.open(new Path(path));
reader = new BufferedReader(new InputStreamReader(fsInput,"UTF-8"),256);
String line = null;
while (true) {
line = reader.readLine();
if(line == null) {
break;
}
System.out.println(line);
}
}catch (Exception e) {
e.printStackTrace();
} finally {
IOUtils.closeStream(reader);
}
}
public static void create(String parent,String file) throws Exception {
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
BufferedWriter writer = null;
try {
FSDataOutputStream fsOut = fs.create(new Path(parent,file),true);
writer = new BufferedWriter(new OutputStreamWriter(fsOut,"UTF-8"));
writer.write("Hello,hadoop!");
writer.newLine();
writer.write("Hello,HDFS!");
writer.flush();
}catch (Exception e) {
e.printStackTrace();
} finally {
writer.close();
}
}
一、Configuration
此类用来加载hadoop的配置文件,hadoop平台下的其他组件(HDFS,Mapreducer,yarn,hbase等)也可以通过它来加载。它类似于java中的Properties类,可以get/set相应的配置项值,不过提供了更多便捷的操作方法,Configuration实例非线程安全。默认情况下Configuration类只依次加载“core-default.xml”、“core-site.xml”配置文件。
1、addDefaultResource(String name): 将指定的配置文件作为默认值加载,Confuguration类内部有一个static类型的CopyOnWriteArrayList,用来保存defaultResources列表,默认此列表中只有"core-default.xml"、"core-site.xml"两个文件,可以通过此方法添加默认resource文件,此后所有的Configuration实例都会加载这些defaultResources。
每个Configuration实例,都会重新加载所有的配置文件(加载文件的过程是同步的),这在某些场景下显得有些“多余”,通常情况下Confuguration实例非线程安全,因为其set方法并没有同步,如果能够对set方法进行同步,我们仍然可以在多线程环境中使用Configuration实例。
2、Configuration的子类有HBaseConfiguration、HdfsConfiguration、YarnConfiguration等;其中HBaseConfiguration额外加载了“hbase-default.xml”、“hbase-site.xml”;HdfsConfiguration额外加载了“hdfs-defaut.xml”、“hdfs-site.xml”;YarnConfiguration额外加载了“yarn-default.xml”、“yarn-site.xml”。
二、FileSystem
这是HDFS的核心API,我们通常使用它来操作HDFS文件系统。FileSystem有多个子类,比如LocalFileSystem、FTPFileSystem、S3FileSystem,以及HDFS中最常用的DistributedFileSystem,和HBase中的HFileSystem等。
1、FileSystem get(Configuration conf): 此方法将会导致,configuration额外的加载core、hdfs、mapred、yarn所有的配置,并根据“fs.defaultFS”配置项返回相应的文件系统:如果以“file://”开头,则返回LocalFileSystem实例,如果以“hdfs://”开头则返回DistributedFileSystem实例;其他的FileSystem类似。FileSystem将使用ServiceLoader类加载META-INF/services目录下“org.apache.hadoop.fs.FileSystem”文件中指定的服务列表,列表中即为HDFS支持的文件系统。
此方法将会根据conf中“fs.defaultFS”配置项指定的文件系统uri,返回指定的FileSystem实例,同时还可以使用get(URI uri,Configuration conf)方法指定uri来覆盖conf中的配置项。
FileSytem类内部有一个static CACHE,用来保存每种文件系统的实例集合,FileSystem类中可以通过"fs.%s.impl.disable.cache"来指定是否缓存FileSystem实例(其中%s替换为相应的scheme,比如hdfs、local、s3、s3n等),默认cache为开启,即一旦创建了相应的FileSystem实例,这个实例将会保存在缓存中,此后每次get都会获取同一个实例;当调用FileSystem#close()方法时,将会从CACHE中移除此实例;如果CACHE中没有匹配的实例,将会实例化。
2、FSDataOutputStream append(Path path): 从文件的尾部写入数据。并非所有的FileSystem子类都支持。不过HDFS文件系统DistributedFileSystem支持。
3、boolean deleteOnExit(Path path): 将delete操作添加到本地cache中,在文件系统关闭时(close方法),再执行删除文件操作。与之相关联的方法还有cancelDeleteOnExit(path),从本地cache中移除一个deleteOnExit删除操作。“deleteOnExit”删除操作,将会在close方法调用时,依次删除(调用delete方法)。
4、void close(): 关闭文件系统,此操作通常被子文件系统重写;此法将会从CACHE中移除此文件系统的实例,执行“deleteOnExit”列表,子系统中还会处理相关的网络链接关闭等操作。通常情况下,我们不会调用close方法,除非确定FileSystem实例不在使用。
5、void concat(Path target,Path[] srcs):