hadoop如何实现FileSystem查询文件系统

43次阅读
没有评论

丸趣 TV 小编给大家分享一下 hadoop 如何实现 FileSystem 查询文件系统,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

文件元数据:Filestatus

任何文件系统的一个重要特征是定位其目录结构及检索其存储的文件和目录信息的能力。FileStatus 类封装了文件系统中文件和目录的元数据,包括文件长度、块大小、副本、修改时间、所有者、所属组以及许可信息。

代码:

public class FileStatus implements Writable, Comparable {
 private Path path;
 private long length;
 private boolean isdir;
 private short block_replication;
 private long blocksize;
 private long modification_time;
 private long access_time;
 private FsPermission permission;
 private String owner;
 private String group;
 
 public FileStatus() { this(0, false, 0, 0, 0, 0, null, null, null, null); }
 public FileStatus(long length, boolean isdir, int block_replication,
 long blocksize, long modification_time, long access_time,
 FsPermission permission, String owner, String group, 
 Path path) {
 this.length = length;
 this.isdir = isdir;
 this.block_replication = (short)block_replication;
 this.blocksize = blocksize;
 this.modification_time = modification_time;
 this.access_time = access_time;
 this.permission = (permission == null) ? 
 FsPermission.getDefault() : permission;
 this.owner = (owner == null) ?   : owner;
 this.group = (group == null) ?   : group;
 this.path = path;
 }
}

FileSystem 的 getFileStatus()提供了获取一个文件或目录的状态对象的方法。例 3 - 5 展示了它的用法。

例 3 -5:展示文件状态信息

public class ShowFileStatusTest { 
 
 private MiniDFSCluster cluster; // use an 
in-process HDFS cluster for testing 
 private FileSystem fs; 
 
 @Before 
 public void setUp() throws IOException { 
 Configuration conf = new Configuration(); 
 if (System.getProperty( test.build.data) == null) { 
 System.setProperty( test.build.data ,  /tmp  
 } 
 cluster = new MiniDFSCluster(conf, 1, true, null); 
 fs = cluster.getFileSystem(); 
 OutputStream out = fs.create(new Path( /dir/file)); 
 out.write(content .getBytes( UTF-8)); 
 out.close(); 
 } 
 
 @After 
 public void tearDown() throws IOException { 
 if (fs != null) { fs.close(); } 
 if (cluster != null) { cluster.shutdown(); } 
 } 
 
 @Test(expected = FileNotFoundException.class) 
 public void throwsFileNotFoundForNonExistentFile()
throws IOException { 
 fs.getFileStatus(new Path( no-such-file)); 
 } 
 
 @Test 
 public void fileStatusForFile() throws IOException { 
 Path file = new Path( /dir/file  
 FileStatus stat = fs.getFileStatus(file); 
 assertThat(stat.getPath().toUri().getPath(), is(/dir/file)); 
 assertThat(stat.isDir(), is(false)); 
 assertThat(stat.getLen(), is(7L)); 
 assertThat(stat.getModificationTime(), 
 is(lessThanOrEqualTo(System.currentTimeMillis()))); 
 assertThat(stat.getReplication(), is((short) 1)); 
 assertThat(stat.getBlockSize(), is(64 * 1024 * 1024L)); 
 assertThat(stat.getOwner(), is(tom)); 
 assertThat(stat.getGroup(), is(supergroup)); 
 assertThat(stat.getPermission().toString(), is( rw-r--r--)); 
 } 
 
 @Test 
 public void fileStatusForDirectory() throws IOException { 
 Path dir = new Path( /dir  
 FileStatus stat = fs.getFileStatus(dir); 
 assertThat(stat.getPath().toUri().getPath(), is(/dir)); 
 assertThat(stat.isDir(), is(true)); 
 assertThat(stat.getLen(), is(0L)); 
 assertThat(stat.getModificationTime(), 
 is(lessThanOrEqualTo(System.currentTimeMillis()))); 
 assertThat(stat.getReplication(), is((short) 0)); 
 assertThat(stat.getBlockSize(), is(0L)); 
 assertThat(stat.getOwner(), is(tom)); 
 assertThat(stat.getGroup(), is(supergroup)); 
 assertThat(stat.getPermission().toString(), is( rwxr-xr-x)); 
 } 
 
}

如果文件或目录不存在,即会抛出 FileNotFoundException 异常。如果你只对文件或目录是否存在有兴趣,exists()方法会更方便

public boolean exists(Path f) throws IOException

  列出文件

查找一个文件或目录的信息很实用,但有时我们还需要能够列出目录的内容。这就是 listStatus()方法的功能:

 public FileStatus[] listStatus(Path f)throws IOException 
public FileStatus[] listStatus(Path f, PathFilter filter) throws IOException 
public FileStatus[] listStatus(Path[] files) throws IOException 
public FileStatus[] listStatus(Path[] files, PathFilter filter) throws IOException

传入参数是一个文件时,它会简单地返回长度为 1 的 FileStatus 对象的一个数组。当传入参数是一个目录时,它会返回 0 或者多个 FileStatus 对象,代表着此目录所包含的文件和目录。

重载方法允许我们使用 PathFilter 来限制匹配的文件和目录,示例参见后文。如果把路径数组作为参数来调用 listStatus 方法,其结果是与依次对每个路径调用此方法,再将 FileStatus 对象数组收集在一个单一数组中的结果是相同的,但是前者更为方便。这在建立从文件系统树的不同部分执行的输入文件的列表时很有用。例 3 - 6 是这种思想的简单示范。注意 FIleUtil 中 stat2Paths()的使用,它将一个 FileStatus 对象数组转换为 Path 对象数组。

例 3 -6:显示一个 Hadoop 文件系统中一些路径的文件信息

public class ListStatus { 
 
 public static void main(String[] args) throws Exception { 
 String uri = args[0]; 
 Configuration conf = new Configuration(); 
 FileSystem fs = FileSystem.get(URI.create(uri), conf); 
 
 Path[] paths = new Path[args.length]; 
 for (int i = 0; i   paths.length; i++) { 
 paths[i] = new Path(args[i]); 
 } 
 
 FileStatus[] status = fs.listStatus(paths); 
 Path[] listedPaths = FileUtil.stat2Paths(status); 
 for (Path p : listedPaths) { 
 System.out.println(p); 
 } 
 } 
}

文件格式

在一步操作中处理批量文件,这个要求很常见。举例来说,处理日志的 MapReduce 作业可能会分析一个月的文件,这些文件被包含在大量目录中。Hadoop 有一个通配的操作,可以方便地使用通配符在一个表达式中核对多个文件,不需要列举每个文件和目录来指定输入。Hadoop 为执行通配提供了两个 FileSystem 方法:

public FileStatus[] globStatus(Path pathPattern) throws IOException 
public FileStatus[] globStatus(Path pathPattern, PathFilter filter) throws IOException

globStatus()返回了其路径匹配于所供格式的 FileStatus 对象数组,按路径排序。可选的 PathFilter 命令可以进一步指定限制匹配。

Hadoop 支持的一系列通配符与 Unix bash 相同(见表 3 -2)。

表 3 -2:通配符及其作用

通配符

名称

匹配

*

星号

匹配 0 或多个字符

问号

匹配单一字符

[ab]

字符类别

匹配 {a,b} 中的一个字符

[^ab]

非字符类别

匹配不是 {a,b} 中的一个字符

[a-b]

字符范围

匹配一个在 {a,b} 范围内的

字符(包括 ab),a 在字典

顺序上要小于或等于 b

[^a-b]

非字符范围

匹配一个不在 {a,b} 范围内

的字符(包括 ab),a 在字

典顺序上要小于或等于 b

{a,b}

或选择

匹配包含 a 或 b 中的一个的语句

\c

转义字符

匹配元字符 c

以下是一些文件通配符及其扩展。

通配符

扩展

/*

/2007/2008

/*/*

/2007/12 /2008/01

/*/12/*

/2007/12/30 /2007/12/31

/200?

/2007 /2008

/200[78]

/2007 /2008

/200[7-8]

/2007 /2008

/200[^01234569]

/2007 /2008

/*/*/{31,01}

/2007/12/31 /2008/01/01

/*/*/3{0,1}

/2007/12/30 /2007/12/31

/*/{12/31,01/01}

/2007/12/31 /2008/01/01

   

PathFilter 对象

通配格式不是总能够精确地描述我们想要访问的文件集合。比如,使用通配格式排除一个特定的文件就不太可能。FileSystem 中的 listStatus()和 globStatus()方法提供了可选的 PathFilter 对象,使我们能够通过编程方式控制匹配:

package org.apache.hadoop.fs; 
 
public interface PathFilter { 
boolean accept(Path path); 
}

PathFilter 与 java.io.FileFilter 一样,是 Path 对象而不是 File 对象。

例 3 - 7 展示了一个 PathFilter,用于排除匹配一个正则表达式的路径。

public class RegexExcludePathFilter implements PathFilter { 
 
 private final String regex; 
 
 public RegexExcludePathFilter(String regex) { 
 this.regex = regex; 
 } 
 
 public boolean accept(Path path) { 
 return !path.toString().matches(regex); 
 } 
}

这个过滤器只留下与正则表达式不同的文件。我们将它与预先剔除一些文件集合的通配配合:过滤器用来优化结果。例如:

s.globStatus(new Path( /2007/*/*), 
new RegexExcludeFilter(^.*/2007/12/31$))

以上是“hadoop 如何实现 FileSystem 查询文件系统”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注丸趣 TV 行业资讯频道!