1、在分布式存儲中,經常會出現節點失效的情況,HDFS可以持續監視,錯誤檢查,容錯處理,自動恢復;
2、分布式存儲的文件都是非常巨大的,HDFS重新規定了每次I/O的塊的大小;
3、對於搜索引擎的業務,大部分都只會在文件尾添加新數據,很少修改已有數據。HDFS做了優化;
4、與應用壹起設計的文件系統API對整個系統的彈性和適用性有很大好處;
5、有效的支持多個客戶端並行添加同壹個文件。
雖然HDFS實現了這麽多的功能,但是因為它已經實現為壹個開源框架,所以對於程序開發者來說,並不需要了解其底層的文件操作,我們可以通過其提供的壹套與linux文件命令類似的命令行工具來進行文件操作。
基本文件命令:
格式為:hadoop fs -cmd <args>
cmd的命名通常與unix對應的命令名相同。例如,文件列表命令: hadoop fs -ls
1、添加目錄和文件
HDFS有壹個默認的工作目錄 /user/$USER,其中$USER是妳的登錄用戶名。不過目錄不會自動建立,我們現在用mkdir建立它,我使用的是chen作為用戶名。
hadoop fs -mkdir /user/chen
(hadoop的mkdir命令會自動創建父目錄,類似於帶-p的unix命令)
我們現在放本地文件系統的壹個文件進去。
hadoop fs -put example.txt .
最後壹個參數是句點,相當於放入了默認的工作目錄,等價於 hadoop fs -put example.txt /user/chen
當妳把文件放入HDFS上後,妳就可以運行Hadoop程序來處理它。
2、檢索文件
get命令與put命令相反,它從HDFS復制文件回到本地文件系統。
hadoop fs -get example.txt .
復制到本地的當前工作目錄中。
另壹種是顯示數據,用cat
hadoop fs -cat example.txt
3、刪除文件
rm命令
hadoop fs -rm example.txt
也可以用來刪除空目錄
編程讀寫HDFS
利用HDFS給我們提供的API,我們同樣可以訪問它。
在Hadoop中用作文件操作的主類位於org.apache.hadoop.fs軟件包中。包括常見的open、read、write、close。Hadoop文件的API起點是FileSystem類,這是壹個與文件系統交互的抽象類,我們通過調用factory的方法FileSystem.get(Configuration conf)來取得所需的FileSystem實例,如下我們可以獲得與HDFS接口的FileSystem對象:
Configuration conf = new Configuration();
FileSystem hdfs = FileSystem.get(conf);//獲得HDFS的FileSystem對象
如果我們要實現HDFS與本地文件系統的交互,我們還需要獲取本地文件系統的FileSystem對象
FileSystem local = FileSystem.getLocal(conf);//獲得本地文件系統的FileSystem對象
以下代碼講解了壹個例子,我們開發壹個PutMerge程序,用於合並本地文件後放入HDFS,因為大文件HDFS處理起來比較容易,所以這個程序經常會在以後的開發中用到
[java] view plain copy
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class PutMerge {
public static void main(String[] args) throws IOException {
[java] view plain copy
Configuration conf = new Configuration();
FileSystem hdfs =FileSystem.get(conf); //獲得HDFS文件系統的對象
FileSystem local = FileSystem.getLocal(conf);//獲得本地文件系統的對象
[java] view plain copy
Path inputDir = new Path(args[0]);//設定輸入目錄
Path hdfsFile = new Path(args[1]);//設定輸出目錄
try{
FileStatus[] inputFiles = local.listStatus(inputDir);//FileStatus的listStatus()方法獲得壹個目錄中的文件列表
FSDataOutputStream out = hdfs.create(hdfsFile);//生成HDFS輸出流
for(int i = 0; i < inputFiles.length; i ++){
System.out.println(inputFiles[i].getPath().getName());
[java] view plain copy
FSDataInputStream in = local.open(inputFiles[i].getPath());//打開本地輸入流
byte[] buffer = new byte[256];
int bytesRead = 0;
while((bytesRead = in.read(buffer))>0){
out.write(buffer,0,bytesRead);//通過壹個循環來寫入
}
in.close();
}
out.close();
}catch (IOException e) {
e.printStackTrace();
}
}