本人博客開始遷移,博客整個架構本身搭建及編碼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版中文版