遍歷hdfs文件夾
A. 用 java遍歷hadoop分布式文件系統中某個目錄下的全部文件,我的hadoop是單節點的
原因:
你訪問的是本地文件系統而非hdfs , 因為Configuration默認的是在core-default.xml中的屬性fs.default.name默認值是file:///,表示本地文件系統。在我們new Configuration();時會默認載入core-default.xml文件,所以根據這個文件的fs.default.name值使用了本地文件系統。
解決方法:
一般安裝hadoop時都是修改core-site.xml文件,這個文件設置的屬性值一般使用來覆蓋core-default.xml這個文件的,在core-site.xml文件中會設置fs.default.name值為hadoop的namenode的地址以及埠號,如hdfs://localhost:9000,即表示namenode是本機,也就是為分布式。所以我們在連接hdfs時需要指定連接的地址,也就是hadoop集群中core-site.xml中fs.default.name屬性值。所以解決方法有三種:
1)在代碼Configuration conf=new Configuration();之後手動為Configuration對象設置fs.default.name屬性值,如:conf.set("fs.default.name","hdfs:localhost:9000");
2)在代碼的classpath下創建一個文件,在文件中設置fs.default.name屬性值,再使用conf.addResource("文件路徑")將該文件添加到Configuration中;
3)直接將集群的core-site.xml添加到classpath下即可,無需手動添加到Configuration,在new Configuration時會自動載入該文件
B. 關於hdfs的物理存儲路徑問題
我沒用過Hive,但HDFS的存儲機制都是一樣的。
你所謂的物理位置指的是在操作系統中的磁碟路徑?
這個路徑是在Hadoop配置的時候寫在hdfs-site.xml文件的dfs.datanode.data.dir欄位里的,在每個datanode的這個文件夾里存著該節點上存儲的所有數據塊block,以blk_打頭。
dfs.namenode.data.dir指定的文件夾在namenode中則存在元數據。
所以即便你知道這個所謂的物理路徑也沒什麼用,數據都是以block形式存在的,大的數據還由好多個block組成,而且每個block還有副本。
C. 編寫一個JAVA類方法,通過該方法可以獲取出存儲在HDFS集群中根目錄的所有文件
public void listMyFile() throws Exception {
//獲取FileSystem
//"hdfs"為偽造用戶,使用hdfs用戶進行訪問
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.83.141:8020"), new Configuration(), "hdfs");
//獲取指定目標目錄下的所有文件信息
RemoteIterator<LocatedFileStatus> iterator =
fileSystem.listFiles(new Path("/"), true);
//遍歷迭代器
while (iterator.hasNext()) {
//獲取每個文件詳細信息
LocatedFileStatus fileStatus = iterator.next();
//獲取每個文件的存儲路徑
System.out.println("路徑:" + fileStatus.getPath() +
"---" + fileStatus.getPath().getName());
//獲取文件的block存儲信息
BlockLocation[] blockLocations = fileStatus.getBlockLocations();
//列印每個文件的block數
System.out.println("block數量:" + blockLocations.length);
//列印每一個block副本的存儲位置
for (BlockLocation blockLocation : blockLocations) {
String[] hosts = blockLocation.getHosts();
for (String host : hosts) {
System.out.println("主機:" + host);
}
}
}
}