上一篇博文我們分享的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. 結果
二. 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. 結果
三. 定位文件讀取
需求:分塊讀取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系列的其他內容,希望大家持續關注博主!