您好,登錄后才能下訂單哦!
小編給大家分享一下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查詢文件系統”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。