前言java
上一篇詳細介紹了HDFS集羣,還有操做HDFS集羣的一些命令,經常使用的命令:apache
hdfs dfs -ls xxx hdfs dfs -mkdir -p /xxx/xxx hdfs dfs -cat xxx hdfs dfs -put local cluster hdfs dfs -get cluster local hdfs dfs -cp /xxx/xxx /xxx/xxx hdfs dfs -chmod -R 777 /xxx hdfs dfs -chown -R zyh:zyh /xxx
注意:這裏要說明一下-cp,咱們能夠從本地文件拷貝到集羣,集羣拷貝到本地,集羣拷貝到集羣。編程
其實在前面配置的每個集羣節點均可以作一個Hadoop客戶端。可是咱們通常都不會拿用來作集羣的服務器來作客戶端,須要單獨的配置一個客戶端。windows
1)安裝JDK服務器
2)安裝Hadoopmaven
3)客戶端配置子core-site.xml分佈式
4)客戶端配置之mapred-site.xmlide
5)客戶端配置之yarn-site.xml工具
以上就搭建了一個Hadoop的客戶端oop
1)org.apache.hadoop.fs.FileSystem
是一個通用的文件系統API,提供了不一樣文件系統的統一訪問方式。
2)org.apache.hadoop.fs.Path
是Hadoop文件系統中統一的文件或目錄描述,相似於java.io.File對本地文件系統的文件或目錄描述。
3)org.apache.hadoop.conf.Configuration
讀取、解析配置文件(如core-site.xml/hdfs-default.xml/hdfs-site.xml等),或添加配置的工具類
4)org.apache.hadoop.fs.FSDataOutputStream
對Hadoop中數據輸出流的統一封裝
5)org.apache.hadoop.fs.FSDataInputStream
對Hadoop中數據輸入流的統一封裝
1)構建Configuration對象,讀取並解析相關配置文件
Configuration conf=new Configuration();
2)設置相關屬性
conf.set("fs.defaultFS","hdfs://1IP:9000");
3)獲取特定文件系統實例fs(以HDFS文件系統實例)
FileSystem fs=FileSystem.get(new URI("hdfs://IP:9000"),conf,「hdfs");
4)經過文件系統實例fs進行文件操做(以刪除文件實例)
fs.delete(new Path("/user/liuhl/someWords.txt"));
有兩個靜態工廠方法來獲取FileSystem實例文件系統。
經常使用的就第二個和第四個
1)使用的是IDEA+Maven來進行測試
2)Maven的pom.xml文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.jxlg.zyh.hadoop</groupId> <artifactId>Hadoop_0010</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>2.8.1</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>2.8.1</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-hdfs</artifactId> <version>2.8.1</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-mapreduce-client-core</artifactId> <version>2.8.1</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-auth</artifactId> <version>2.8.1</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>19.0</version> </dependency> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.2</version> </dependency> <dependency> <groupId>commons-cli</groupId> <artifactId>commons-cli</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>commons-configuration</groupId> <artifactId>commons-configuration</artifactId> <version>1.9</version> </dependency> <dependency> <groupId>org.apache.avro</groupId> <artifactId>avro</artifactId> <version>1.7.7</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.5</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.0.0</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-my-jar-with-dependencies</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>3.0.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
3)HDFS集羣一個NameNode和兩個DataNode
package com.jslg.zyh.hadoop.hdfs; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.URI; public class CatDemo_0010 { public static void main(String[] args) throws IOException { // 建立Configuration對象 Configuration conf=new Configuration(); // 建立FileSystem對象 FileSystem fs= FileSystem.get(URI.create(args[0]),conf); // 需求:查看/user/kevin/passwd的內容 // args[0] hdfs://1.0.0.5:9000/user/zyh/passwd // args[0] file:///etc/passwd FSDataInputStream is= fs.open(new Path(args[0])); byte[] buff=new byte[1024]; int length=0; while((length=is.read(buff))!=-1){ System.out.println( new String(buff,0,length)); } System.out.println( fs.getClass().getName()); } }
1)須要在HDFS文件系統中有passwd.txt文件,若是沒有須要本身建立
hdfs dfs -mkdir -p /user/zyh
hdfs dfs -put /etc/passwd /user/zyh/passwd.txt
2)將Maven打好的jar包發送到服務器中,這裏咱們就在NameNode主機中執行,每個節點都是一個客戶端。
注意:
這裏要發送第二個包,由於它把相關類也打進jar中
查看服務器已經收到jar包
3)執行jar包查看結果
咱們能夠看到查詢出來了passwd.txt中的內容
注意:在最後咱們還查看了一下FileSystem類,由於咱們知道FileSystem是抽象類,它是根據後面的URI來肯定到底調用的是哪個子類的。
1)主要代碼
public static void main(String[] args) throws IOException { //建立configuration對象 Configuration conf = new Configuration(); //建立FileSystem對象 //需求:查看hdfs集羣服務器/user/zyh/passwd.txt的內容 FileSystem fs = FileSystem.get(URI.create("hdfs://1.0.0.5:9000/user/zyh/passwd.txt"), conf); // args[0] hdfs://1.0.0.3:9000/user/zyh/passwd.txt // args[0] file:///etc/passwd.txt FSDataInputStream is = fs.open(new Path("hdfs://1.0.0.5:9000/user/zyh/passwd.txt")); OutputStream os=new FileOutputStream(new File("D:/a.txt")); byte[] buff= new byte[1024]; int length = 0; while ((length=is.read(buff))!=-1){ System.out.println(new String(buff,0,length)); os.write(buff,0,length); os.flush(); } System.out.println(fs.getClass().getName()); //這個是根據你傳的變量來決定這個對象的實現類是哪一個 }
2)Maven從新編譯,並執行
3)結果
在控制檯中:
在本地文件中:
1)主要代碼
public class GetDemo_0010 { public static void main(String[] args) throws IOException { Configuration conf= new Configuration(); // 獲取從集羣上讀取文件的文件系統對象 // 和輸入流對象 FileSystem inFs= FileSystem.get( URI.create(args[0]),conf); FSDataInputStream is= inFs.open(new Path(args[0])); // 獲取本地文件系統對象 //固然這個你也能夠用FileOutputStream LocalFileSystem outFs= FileSystem.getLocal(conf); FSDataOutputStream os= outFs.create(new Path(args[1])); byte[] buff=new byte[1024]; int length=0; while((length=is.read(buff))!=-1){ os.write(buff,0,length); os.flush(); } System.out.println( inFs.getClass().getName()); System.out.println( is.getClass().getName()); System.out.println( outFs.getClass().getName()); System.out.println( os.getClass().getName()); os.close(); is.close(); } }
2)結果
咱們能夠看到對於HDFS集羣中獲取的FileSystem對象是分佈式文件系統,而輸入流是HdfsDataInputStream主要用來作數據的傳輸。
對於本地來講獲取到的FileSystem對象時本地文件系統,而輸出流就是FSDataOutputStream。
將HDFS中的文件拿到windows中:
//建立configuration對象
Configuration conf = new Configuration();
// 獲取從集羣上讀取文件的文件系統對象 // 和輸入流對象 FileSystem inFs= FileSystem.get( URI.create("file://1.0.0.5:9000/user/kevin/passwd"),conf); FSDataInputStream is= inFs.open(new Path("hdfs://1.0.0.5:9000/user/kevin/passwd")); // 獲取本地文件系統對象 LocalFileSystem outFs= FileSystem.getLocal(conf); FSDataOutputStream os= outFs.create(new Path("C:\\passwd")); byte[] buff=new byte[1024]; int length=0; while((length=is.read(buff))!=-1){ os.write(buff,0,length); os.flush(); } System.out.println( inFs.getClass().getName()); System.out.println( is.getClass().getName()); System.out.println( outFs.getClass().getName()); System.out.println( os.getClass().getName()); os.close(); is.close();
這裏須要藉助Hadoop中的一個類Configured、一個接口Tool、ToolRunner(主要用來運行Tool的子類也就是run方法)
分析:
1)咱們查看API能夠看到ToolRunner中有一個run方法:
裏面須要一個Tool的實現類和使用args用來傳遞參數的String類型的數據
2)分析Configured
這是Configurable接口中有一個getConf()方法
而在Configured類中實現了Configurable接口
因此Configured類中實現了Configurable接口的getConf()方法,使用它來得到一個Configuration對象
3)細說Configuration對象
能夠獲取Hadoop的全部配置文件中的數據
還能夠經過使用命令行中使用-D(-D是一個標識)使用的變量以及值
1)主要代碼
import java.net.URI; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configured; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FSDataOutputStream; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.util.Tool; import org.apache.hadoop.util.ToolRunner; public class GetDemo_0011 extends Configured implements Tool{ @Override public int run(String[] strings) throws Exception{ //咱們全部的代碼都寫在這個run方法中 Configuration conf= getConf(); String input=conf.get("input"); String output=conf.get("output"); FileSystem inFs= FileSystem.get( URI.create(input),conf); FSDataInputStream is= inFs.open(new Path(input)); FileSystem outFs= FileSystem.getLocal(conf); FSDataOutputStream os= outFs.create(new Path(output)); IOUtils.copyBytes(is,os,conf,true); return 0; } public static void main(String[] args) throws Exception{ //ToolRunner中的run方法中須要一個Tool的實現類,和 System.exit( ToolRunner.run( new GetDemo_0011(),args)); } }
分析:
1)介紹IOUtils
它是Hadoop的一個IO流的工具類,查看API中可知!
2)打包jar發送給服務器執行
3)查看結果
1)普通版
import java.net.URI; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configured; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FSDataOutputStream; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.LocalFileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.util.Tool; import org.apache.hadoop.util.ToolRunner; public class P00032_HdfsDemo_PutFile_0010 extends Configured implements Tool{ @Override public int run(String[] strings) throws Exception{ Configuration configuration =getConf(); String input= configuration.get("input"); String output= configuration.get("output"); LocalFileSystem inFs= FileSystem.getLocal( configuration); FileSystem outFs= FileSystem.get( URI.create(output), configuration); FSDataInputStream is= inFs.open(new Path(input)); FSDataOutputStream os= outFs.create(new Path(output)); IOUtils.copyBytes(is,os,1024,true); System.out.println(os.getClass().getName()); inFs.close(); outFs.close(); return 0; } public static void main(String[] args) throws Exception{ System.exit(ToolRunner.run(new P00032_HdfsDemo_PutFile_0010(),args)); } }
2)能夠觀察到寫入了多少
import java.io.IOException; import java.net.URI; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configured; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FSDataOutputStream; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.LocalFileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.util.Tool; import org.apache.hadoop.util.ToolRunner; public class P00031_HdfsDemo_PutFile_0010 extends Configured implements Tool{ FSDataOutputStream os=null; @Override public int run(String[] strings) throws Exception{ Configuration configuration=getConf(); String input=configuration.get("input"); String output=configuration.get("output"); LocalFileSystem inFs=FileSystem.getLocal(configuration); FileSystem outFs=FileSystem.get(URI.create(output),configuration); FSDataInputStream is=inFs.open(new Path(input)); os=outFs.create(new Path(output),()->{ try{ System.out.println("已經寫入了"+os.getPos()+"bytes"); }catch(IOException e){ e.printStackTrace(); } }); IOUtils.copyBytes(is,os,1024,true); System.out.println(os.getClass().getName()); inFs.close(); outFs.close(); return 0; } public static void main(String[] args) throws Exception{ System.exit(ToolRunner.run(new P00031_HdfsDemo_PutFile_0010(),args)); } }
喜歡就「推薦」哦!