HDFS系列(7) | HDFS的 I/O流 API操作

上一篇博文我們分享的API操作HDFS系統都是框架封裝好的。那麼如果我們想自己實現上述API的操作該怎麼實現呢?
此次物品們介紹的是採用I/O流的方式實現數據的上傳和下載。


一. HDFS文件上傳

需求:把本地d盤上的lisen.txt文件上傳到HDFS根目錄

  • 1. 代碼
package com.buwenbuhuo.hdfs;


import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;
import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

/**
 * @author buwenbuhuo
 * @create 2020-04-22 18:26
 * com.buwenbuhuo.hdfs - the name of the target package where the new class or interface will be created.
 * hdfs0422 - the name of the current project.
 */
public class HDFSClient {
    @Test
    public void putFileToHDFS() throws IOException, InterruptedException, URISyntaxException {

        // 1 獲取文件系統
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(URI.create("hdfs://hadoop001:9000"), configuration, "bigdata");

        // 2 創建輸入流
        FileInputStream fis = new FileInputStream(new File("d:/lisen.txt"));

        // 3 獲取輸出流
        FSDataOutputStream fos = fs.create(new Path("/lisen.txt"));

        // 4 流對拷
        IOUtils.copyBytes(fis, fos, configuration);

        // 5 關閉資源
        IOUtils.closeStream(fos);
        IOUtils.closeStream(fis);
        fs.close();


        }
    }

  • 2. 結果
    1

二. HDFS文件下載

需求:從HDFS上下載lisen.txt文件到本地d盤上

  • 1.代碼
// 文件下載
@Test
public void getFileFromHDFS() throws IOException, InterruptedException, URISyntaxException{

	// 1 獲取文件系統
	Configuration configuration = new Configuration();
	FileSystem fs = FileSystem.get(URI.create("hdfs://hadoop001:9000"), configuration, "bigdata");
		
	// 2 獲取輸入流
	FSDataInputStream fis = fs.open(new Path("/lisen.txt"));
		
	// 3 獲取輸出流
	FileOutputStream fos = new FileOutputStream(new File("d:/lisen1.txt"));
		
	// 4 流的對拷
	IOUtils.copyBytes(fis, fos, configuration);
		
	// 5 關閉資源
	IOUtils.closeStream(fos);
	IOUtils.closeStream(fis);
	fs.close();
}

  • 2. 結果
    2

三. 定位文件讀取

需求:分塊讀取HDFS上的大文件,比如根目錄下的/hadoop-2.7.2.tar.gz

  • 1. 下載第一塊
@Test
public void readFileSeek1() throws IOException, InterruptedException, URISyntaxException{

	// 1 獲取文件系統
	Configuration configuration = new Configuration();
	FileSystem fs = FileSystem.get(URI.create("hdfs://hadoop001:9000"), configuration, "bigdata");
		
	// 2 獲取輸入流
	FSDataInputStream fis = fs.open(new Path("/hadoop-2.7.2.tar.gz"));
		
	// 3 創建輸出流
	FileOutputStream fos = new FileOutputStream(new File("d:/hadoop-2.7.2.tar.gz.part1"));
		
	// 4 流的拷貝
	byte[] buf = new byte[1024];
		
	for(int i =0 ; i < 1024 * 128; i++){
		fis.read(buf);
		fos.write(buf);
	}
		
	// 5關閉資源
	IOUtils.closeStream(fis);
	IOUtils.closeStream(fos);
fs.close();
}

  • 2. 下載第二塊
@Test
public void readFileSeek2() throws IOException, InterruptedException, URISyntaxException{

	// 1 獲取文件系統
	Configuration configuration = new Configuration();
	FileSystem fs = FileSystem.get(URI.create("hdfs://hadoop001:9000"), configuration, "bigdata");
		
	// 2 打開輸入流
	FSDataInputStream fis = fs.open(new Path("/hadoop-2.7.2.tar.gz"));
		
	// 3 定位輸入數據位置
	fis.seek(1024*1024*128);
		
	// 4 創建輸出流
	FileOutputStream fos = new FileOutputStream(new File("d:/hadoop-2.7.2.tar.gz.part2"));
		
	// 5 流的對拷
	IOUtils.copyBytes(fis, fos, configuration);
		
	// 6 關閉資源
	IOUtils.closeStream(fis);
	IOUtils.closeStream(fos);
}

  • 3. 合併文件
    在Window命令窗口中進入到目錄D:\,然後執行如下命令,對數據進行合併
type hadoop-2.7.2.tar.gz.part2 >> hadoop-2.7.2.tar.gz.part1

合併完成後,將hadoop-2.7.2.tar.gz.part1重新命名爲hadoop-2.7.2.tar.gz。解壓發現該tar包非常完整。


爲了方便大家理解,在代碼中博主都寫有註釋,因此在這裏就不作過多的過程說明了。那麼本次的分享就到這裏了,小夥伴們有什麼疑惑或好的建議可以積極在評論區留言,博主後續還會推出HDFS系列的其他內容,希望大家持續關注博主!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章