HDFS的java API操作(基於Windows平台的Eclipse)


hdfs在生產應用中主要是針對客戶端的開發,從hdfs提供的api中構造一個HDFS的訪問客戶端對象,然后通過該客戶端對象操作(增刪改查)HDFS上的文件。

搭建開發環境

方式一(windows環境下):

1、將官網下載的hadoop安裝包解壓,並記住下圖所示的目錄

2、創建java project,右鍵工程--->build path--->Configure build path

3、進行如下圖操作

4、進行如下圖操作

5、導入jar包(圖示目錄下的common包以及lib目錄下的所有包 還有hdfs包以及其lib目錄下的所有jar包)

6、配置環境變量


7、重要!重要!重要!!!

將安裝包下的lib和bin目錄用對應windows版本平台編譯的本地庫替換(編譯源碼包可自行百度一下相關步驟,或是直接下載別人編譯好的bin和lib)

方式二:

1、創建maven項目

2、將maven項目的JRE換成自己機器上的1.7(默認是1.5的版本)

3、寫入pom文件

<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.xiaojie</groupId>
<artifactId>hdfs</artifactId>
<version>0.0.1-SNAPSHOT</version>

<dependencies>
<!-- <hadoop.version>2.6.5</hadoop.version> -->
	<dependency>
		<groupId>org.apache.hadoop</groupId>
		<artifactId>hadoop-common</artifactId>
		<version>2.6.5</version>
	</dependency>

	<dependency>
		<groupId>jdk.tools</groupId>
		<artifactId>jdk.tools</artifactId>
		<version>1.7</version>
		<scope>system</scope>
		<systemPath>${JAVA_HOME}/lib/tools.jar</systemPath>
	</dependency>

	<dependency>
		<groupId>org.apache.hadoop</groupId>
		<artifactId>hadoop-hdfs</artifactId>
		<version>2.6.5</version>
	</dependency>
</dependencies>
</project>

上傳文件

package hadoop;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.util.Iterator;
import java.util.Map.Entry;

import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.BlockLocation;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;
import org.junit.Before;
import org.junit.Test;



public class HdfsClientDemo {
	
	FileSystem fs = null;
	Configuration conf = null;
	@Before
	public void init() throws Exception{
		// new Configuration();的時候,它就會去加載jar包中的hdfs-default.xml
		// 然后再加載classpath下的hdfs-site.xml
		conf = new Configuration();
		
/*		如果我們的代碼中沒有指定fs.defaultFS,並且工程classpath下也沒有給定相應的配置,
		conf中的默認值就來自於hadoop的jar包中的core-default.xml,默認值為: 
		file:///,則獲取的將不是一個DistributedFileSystem的實例,而是一個本地文件系統的客戶端對象*/
		
		// 參數優先級: 1、客戶端代碼中設置的值 2、classpath下的用戶自定義配置文件 3、然后是服務器的默認配置
		 
//		我們要訪問的hdfs的URI
		conf.set( "fs.defaultFS", "hdfs://192.168.25.13:9000");
			
//		獲得hdfs文件系統實例對象,以root身份鏈接        java.net.URI
		fs = FileSystem.get(new URI("hdfs://192.168.25.13:9000"),conf,"root");

	}



//	上傳文件
	@Test
	public void upload() throws Exception{
		fs.copyFromLocalFile(new Path("c:/test.txt"), new Path("/"));
		fs.close();
	}

	
//	使用流的方式上傳文件
	@Test
	public void upload() throws IllegalArgumentException, IOException{
//		true表示是否覆蓋原文件
		FSDataOutputStream out = fs.create(new Path("/stream.tex"),true);
		FileInputStream in = new FileInputStream("c:/test2.txt");
//		org.apache.commons.io下的IOUtils
		IOUtils.copy(in, out);
	}
}

使用hdfs的web工具,查看是否上傳成功

下載文件

注意:

若上面開發環境搭建過程中hadoop報下的bin包和lib包兼容有問題則download()方法會執行失敗(linux下開發不會報錯)。

解決方法1:在自己的windows電腦上編譯hadoop源碼,用編譯后的bin和lib替換。

解決方法2:使用download2()的方法下載。

//	下載文件
	@Test
	public void download() throws Exception {
		fs.copyToLocalFile(new Path("/test2.txt"), new Path("c:/t22.txt"));
		fs.close();
	}



//	下載文件兼容版
//  以流的方式下載
	@Test
	public void download2() throws Exception {
		FSDataInputStream in = fs.open(new Path("/test2.txt"));
		OutputStream out = new FileOutputStream("c:/t23.txt");
//		org.apache.commons.io.IOUtils(common中的和hadoop中的IOUtils都可以,有點小差別)
		IOUtils.copy(in, out);
	}



//	可自定從哪里開始讀以及讀幾個字節,以流的方式
	@Test
	public void diy() throws IllegalArgumentException, IOException{
		FSDataInputStream in = fs.open(new Path("/test2.txt"));
//		指定從哪個字節開始讀
		in.seek(5);
		FileOutputStream out = new FileOutputStream("c:/t22.txt");
		IOUtils.copy(in, out);
//		IOUtils.copyLarge(input, output, inputOffset, length)
	}
	

	
//	指定打印到屏幕,以流的方式
	@Test
	public void diy2() throws IllegalArgumentException, IOException{
		FSDataInputStream in = fs.open(new Path("/test2.txt"));
//		指定從哪個字節開始讀
		in.seek(5);
		IOUtils.copy(in, System.out);
	}

打印配置文件信息

//	打印配置文件
	@Test
	public void printtConf(){
		Iterator<Entry<String, String>> it = conf.iterator();
		while(it.hasNext()){
			Entry<String, String> ent = it.next();
			System.out.println(ent.getKey()+":"+ent.getValue());
		}	
	}

創建目錄

//創建目錄
	@Test
	public void mkdir() throws IllegalArgumentException, IOException{
//		可遞歸創建目錄,返回值表示是否創建成果
		boolean b = fs.mkdirs(new Path("/mkdir"));
		System.out.println(b);
	}

刪除目錄或文件

//	刪除目錄或文件
	@Test
	public void delete() throws IllegalArgumentException, IOException{
//		true表示遞歸刪除,返回值表示是否刪除成功
		boolean b = fs.delete(new Path("/test"), true);
		System.out.println(b);
	}

打印指定路徑下的文件信息(不含目錄,可遞歸)

//	打印指定路徑下的文件信息
	@Test
	public void listFile() throws FileNotFoundException, IllegalArgumentException, IOException{
//		true表示是否遞歸  返回的是迭代器對象
		RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);
		
		while(listFiles.hasNext()){
			LocatedFileStatus file = listFiles.next();
			System.out.println("owner:"+file.getOwner());
			System.out.println("filename:"+file.getPath().getName());
			System.out.println("blocksize:"+file.getBlockSize());
			System.out.println("replication:"+file.getReplication());
			System.out.println("permission:"+file.getPermission());
			BlockLocation[] blockLocations = file.getBlockLocations();
			for (BlockLocation b : blockLocations) {
				System.out.println("塊的起始偏移量:"+b.getOffset());
				System.out.println("塊的長度:"+b.getLength());
				String[] hosts = b.getHosts();
				for (String host : hosts) {
					System.out.println("塊所在的服務器:"+host);
				}
			}

			System.out.println("=========================================");
		}
	}

打印指定路徑下的目錄或文件信息(不可遞歸)

//	打印指定路徑下的文件或目錄
	@Test
	public void list() throws FileNotFoundException, IllegalArgumentException, IOException{
//		返回的是數組,不能遞歸目錄中的內容
		FileStatus[] listStatus = fs.listStatus(new Path("/"));
		for(FileStatus fs: listStatus){
			System.out.println((fs.isFile()?"file:":"directory:")+fs.getPath().getName());
		}
	}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM