1.文件操作
1)上傳本地文件到HDFS
2)讀取文件
3)在hadoopfs中新建文件,並寫入
4)重命名文件
5)刪除hadoopfs上的文件
2.目錄操作
1)讀取某個目錄下的所有文件
2)在hadoopfs上創建目錄
3)刪除目錄
3. HDFS信息
1)查找某個文件在HDFS集羣的位置
2)獲取HDFS集羣上所有節點名稱信息
準備工作:
1、新建一個project項目,添加lib文件夾,將圖示的jar文件添加到文件夾中,並將其add to built path。如圖示。
2、添加conf文件夾,將core-site.xml和hdfs-site.xml兩個文件拷貝到conf下面。刷新。主要作用是配置主機地址。
3、編譯環境和運行環境都是用1.7版本,即jdk1.7和jre1.7。本實驗使用的是Eclipse indigo-windows-32bit和jdk1.7-32bit。
4、此處暫時不需要hadoop-plugin插件,有的話也不影響,但是主機hosts文件要配置好,就是在主機cmd命令中可以通過域名訪問CentOS端NameNode主機。
HDFS 文件讀取流程
1.Client調用FileSystem.open()方法:
1)FileSystem通過RPC與NN通信,NN返回該文件的部分或全部block列表(含有block拷貝的DN地址)。
2)選取距離客戶端最近的DN建立連接,讀取block,返回FSDataInputStream。
2.Client調用輸入流的read()方法:
1)當讀到block結尾時,FSDataInputStream關閉與當前DN的連接,併爲讀取下一個block尋找最近DN。
2)讀取完一個block都會進行checksum驗證,如果讀取DN時出現錯誤,客戶端會通知NN,然後再從下一個擁有該block拷貝的DN繼續讀。
3)如果block列表讀完後,文件還未結束,FileSystem會繼續從NN獲取下一批block列表。
3.關閉FSDataInputStream
HDFS 文件寫入流程
1.Client調用FileSystem的create()方法:
1)FileSystem向NN發出請求,在NN的namespace裏面創建一 新文件,但是並不關聯任何塊。
2)NN檢查文件是否已存在、操作權限。如果檢查通過,NN記錄新文件信息,並在某一個DN上創建數據塊。
3)返回FSDataOutputStream,將Client引導至該數據塊執行寫入操作。
2.Client調用輸出流的write()方法:HDFS默認將每個數據塊放置3份。
FSDataOutputStream將數據首先寫到第一節點,第一節點將數據包傳送並寫入第二節點,第二節點=》第三節點。
3.Client調用流的close()方法:flush緩衝區的數據包,block完成複製份數後,
NN返回成功消息。
代碼如下:
1、添加一個包(packet),org.dragon.hadoop.hdfs.utils,添加一個HDFSUtils.java文件,文件裏面內容如下
package org.dragon.hadoop.hdfs.utils; import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; /** * @author ZhuXY * @time 2016-3-6 下午8:17:10 */ public class HDFSUtils { public static FileSystem getFileSystem() throws IOException, Exception { // 獲取配置 Configuration conf = new Configuration(); // 獲取文件系統 FileSystem hdfs = FileSystem.get(conf); return hdfs; } }
2、下面就是文件操作的正式內容,其中就行Junit 4進行測試,Junit添加直接可以,網上教程很多,將此庫文件包含到項目中就可以了。
代碼中算法列表:
package org.dragon.hadoop.hdfs; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.BlockLocation; 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; import org.apache.hadoop.hdfs.DistributedFileSystem; import org.apache.hadoop.hdfs.protocol.DatanodeInfo; import org.apache.hadoop.io.IOUtils; import org.dragon.hadoop.hdfs.utils.HDFSUtils; import org.junit.Test; /** * @author ZhuXY * @time 2016-3-6 下午5:57:53 通過FileSystem API 操作HDFS */ /** * 步驟:1、將5個jar包考到lib目錄下 * 2、新建一個conf文件夾,然後將core-site.xml和hdfs-site.xml兩個文件考到其下 * 原因:添加配置文件信息識別文件系統 * 3、創建一個文件系統 * 4、 打開輸出流 * 5、read * 6、close * @author ZhuXY * */ public class HDFSFsTest { //讀取當前系統中的文件 @Test public void testRead() throws Exception { // 獲取配置 Configuration conf = new Configuration(); // 獲取文件系統 FileSystem hdfs = FileSystem.get(conf); // 文件名稱 Path path = new Path("/opt/input/touch3.data"); // 打開文件輸入流----------open FSDataInputStream instream = hdfs.open(path); // 讀取文件到控制檯顯示--------read IOUtils.copyBytes(instream, System.out, 4096, false); // 關閉流---------------close IOUtils.closeStream(instream); } //列出當前文件和目錄 @Test public void testList() throws Exception { // 獲取配置 Configuration conf = new Configuration(); // 獲取文件系統 FileSystem hdfs = FileSystem.get(conf); Path path = new Path("/wc"); FileStatus[] fileStatus = hdfs.listStatus(path); for (FileStatus fs : fileStatus) { Path p = fs.getPath(); String info = fs.isDir() ? "目錄" : "文件"; // System.out.println("5"); System.out.println(info + ":" + p); } } //對上傳的文件重命名 @Test public void testRename() throws Exception{ FileSystem fsFileSystem=HDFSUtils.getFileSystem(); //HDFS 文件上傳路徑 Path srcPath=new Path("/opt/input/touch3.data"); Path destPath=new Path("/opt/input/rename.data"); boolean flag=fsFileSystem.rename(srcPath, destPath); System.out.println(flag); } //創建文件,連同目錄一起創建 @Test public void testCreate() throws Exception{ FileSystem hdfsFileSystem=HDFSUtils.getFileSystem(); //HDFS文件上傳路徑 Path path=new Path("/wc/test/touch.data"); //創建文件,並獲取輸出流 FSDataOutputStream fsDataOutputStream=hdfsFileSystem.create(path); //通過輸出流寫入數據 // fsDataOutputStream.writeUTF("你好,hadoop!"); fsDataOutputStream.write("你好".getBytes()); fsDataOutputStream.writeUTF("hadoop!"); IOUtils.closeStream(fsDataOutputStream); } //刪除文件 @Test public void testRemove() throws Exception{ FileSystem fsFileSystem=HDFSUtils.getFileSystem(); Path path=new Path("/opt/input/touch3.data"); boolean flag=fsFileSystem.deleteOnExit(path); System.out.println(flag); } //刪除目錄 @Test public void testRemoveDir() throws Exception { FileSystem fsFileSystem=HDFSUtils.getFileSystem(); Path path=new Path("/opt/input/"); boolean flag=fsFileSystem.delete(path,true); System.out.println(flag); } //上傳文件---put copyFromLocal @Test public void testPut() throws Exception { FileSystem fsFileSystem=HDFSUtils.getFileSystem(); Path srcPath=new Path("C:/jdk-8u73-linux-x64.tar.gz"); //HDFS上傳文件路徑 Path destPath=new Path("/wc/123/"); //此處目錄如果不存在會保存在/wc目錄下,取名123 fsFileSystem.copyFromLocalFile(srcPath, destPath); } //查看某個文件在HDFS集羣中的位置 @Test public void testLocation() throws Exception { FileSystem fsFileSystem=HDFSUtils.getFileSystem(); //HDFS上傳文件路徑 Path path=new Path("/wc/123/"); FileStatus fsFileStatus=fsFileSystem.getFileStatus(path); //獲得所有的塊所在的位置信息包括:主機名,塊名稱、塊大小etc BlockLocation[] blockLocations=fsFileSystem.getFileBlockLocations(fsFileStatus,0,fsFileStatus.getLen()); for(BlockLocation blockLocation:blockLocations){ String[] hostStrings=blockLocation.getHosts();//獲取所在的主機 //System.out.println(hostStrings);//這樣寫不行 //System.out.println(hostStrings[0]);//這樣寫可以 for(String host:hostStrings) System.out.println(host); } } //獲取集羣中所有的節點的名稱信息 @Test public void testCluster() throws Exception { FileSystem fsFileSystem=HDFSUtils.getFileSystem(); //將文件系統強制轉換爲分佈式文件系統 DistributedFileSystem distributedFileSystem=(DistributedFileSystem)fsFileSystem; //獲取文件系統中數據狀態信息 DatanodeInfo[] datanodeInfos=distributedFileSystem.getDataNodeStats(); //循環遍歷 for(DatanodeInfo datanodeInfo:datanodeInfos){ String hostnameString=datanodeInfo.getHostName(); System.out.println(hostnameString); } } }
學習內容
1、學習使用代碼追蹤工具,光標移動到類名,然後按住Ctril鍵出現小手的時候,單擊,然後Attach Source就可以了,可以使源碼文件,還是不如行的話重啓一下Eclipse就行了,實驗中遇到這種情況。
2、學習快捷鍵的使用,註釋alt+/,將一行代碼上移一行alt+|(向上箭頭),複製上移ctril+alt+|(向上箭頭),刪除一行Ctrl+d,快速對齊Ctrl+shift+F,打開源碼搜素open type Ctrl+shift+T,打開outline是ctrl+o等。
3、特別注意的是core-site.xml中的主機地址一定要配置好。