本人博客开始迁移,博客整个架构本身搭建及编码http://www.cookqq.com/listBlog.actionjava
文件元数据:Filestatus 正则表达式
任何文件系统的一个重要特征是定位其目录结构及检索其存储的文件和目录信息的能力。FileStatus类封装了文件系统中文件和目录的元数据,包括文件长度、块大小、副本、修改时间、全部者、所属组以及许可信息。 apache
代码:编程
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:展现文件状态信息bash
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
列出文件 less
查找一个文件或目录的信息很实用,但有时咱们还须要可以列出目录的内容。这就是listStatus()方法的功能:oop
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权威指南第2版中文版