Hadoop 核心-HDFS
前面提過,大資料的特點是: 體量大 型別繁多 值密度低 產生和處理速度快,
當資料集的大小超過一臺獨立的物理計算機的存盤能力時:
就必須對它進行磁區并存盤到若干臺單獨的計算機上,然后將這些計算機通過網路連接,
并對網路中的檔案系統進行集中管理 , 由此構成分布式檔案系統 (HDFS)
HDFS概述
介紹:
在現代的企業環境中,單機容量往往無法存盤大量資料,需要跨機器存盤,
統一管理分布在 :集群上的檔案系統稱為分布式檔案系統
HDFS(Hadoop Distributed File System)是 Apache Hadoop 專案的一個子專案Hadoop 非常適于存盤
大型資料(比如 TB 和 PB) ,
其就是使用HDFS 作為存盤系統HDFS 使用多臺計算機 集群 存盤檔案,
并且提供統一的訪問介面, 像是訪問一個普通檔案系統一樣使用分布式檔案系統.Google 發布了三篇論文, 被稱作為三駕馬車, 其中有一篇叫做
GFS
是描述了 Google 內部的一個叫做 GFS 的分布式大規模檔案系統 :具有強大的可伸縮性和容錯性
Doug Cutting 后來根據GFS的論文, 創造了一個新的檔案系統, 叫做HDFS
適合的應用場景
存盤非常大的檔案:
- 這里非常大指的是幾百M、G、或者TB級別,適合需要
高吞吐量,對延時沒有要求的程式,采用流式的資料訪問方式:
一次寫入、多次讀取資料集經常從資料源生成或者拷貝一 次,然后在其上做很多分析作業 ,運行于商業硬體上:
- Hadoop不需要特別貴的機器,可運行于普通廉價機器;
同樣,HDFS也存在缺點 以下應用就不適合在HDFS上運行:
低延時的資料訪問:
- 不適合對延時要求在毫秒級別的應用,HDFS是為高吞吐資料傳輸設計的,因此可能
犧牲延時無法大量的存盤小檔案:
- 大量小檔案,
元資料保存在NameNode的記憶體中,
整個檔案系統的檔案數量會受限于NameNode的記憶體大小;
NameNode相當于一個老大, 手下有很多的DataNode小弟, 小弟存盤檔案資料, 老大只需要記錄不同小弟存盤的資料;
當老大的記憶體滿了就不能記錄小弟了無論是大資料還是 1kb小資料 , 記錄都在 老大NameNode 的 元資料中…不支持多用戶
寫入/修改檔案:
- 寫入/修改, 都是基于
流訪問:
目前在HDFS 的一個檔案,同時只能有一個用戶寫入 , 并且只能寫在檔案末尾…(還有待升級!!)
HDFS 的架構
HDFS是一個 主/從(Mater/Slave)體系結構
HDFS由四部分組成,HDFS Client、NameNode、DataNode和Secondary NameNode,
Client:就是客戶端
檔案切分:
- 檔案上傳 HDFS 的時候,Client 將檔案切分成 一個一個的Block,
檔案塊:如圖DataNode數字編號的方塊
— 它是檔案存盤理的最小邏輯單元,默認塊大小為64MB.- 使用檔案塊的好處是:
檔案的所有塊并不需要存盤在同一個磁盤上,可以利用集群上的任意一個磁盤進行存盤,
對分布式系統來說,由于塊的大小是固定的,因此計算單個磁盤能存盤多少個塊就相對容易可簡化存盤管理,
在資料冗余備份時, 將每個塊復制到幾臺獨立的機器上(默認為三臺)
可以確保在塊、磁盤或機器發生故障后資料不會丟失,如果發現一個塊不可用,系統會從其他地方讀取另個副本這個程序對用戶是透明的NameNode和DataNode節點:
NameNode:就是 master,它是一個主管、管理者,
- NameNode 負責管理檔案系統的命名空間,屬于
管理者角色,
它維護檔案系統樹內所有檔案和目錄,記錄每個檔案在各個DataNode.上的位置和副本資訊:并協調客戶端對檔案的訪問,
這些資訊以兩種形式存在:命名空間鏡像檔案 edits_*和編輯日志檔案 fsimage_*- NameNode元資料:
NameNode在記憶體中保存著整個檔案系統的名稱 空間和檔案資料塊的地址映射
整個HDFS可存盤的檔案數受限于NameNode的記憶體大小;
位于NameNode節點node1的:hadoop/ dfs/name/ current目錄 (由hdfs-site.xml中的dfs .namenode. name. dir 屬性指定)- NameNode心跳機制
全權管理資料塊的復制,周期性的接受心跳和塊的狀態報告資訊(包含該DataNode上所有資料塊的串列)
若接受到心跳資訊,NameNode認為DataNode作業正常,
如果在10分鐘后還接受到不到DN的心跳,那么NameNode認為DataNode已經宕機 ,
這時候NN準備要把DN上的資料塊進行重新的復制,
確保DataNode 穩定, 進行存盤/記錄/備份...操作, 確保程式穩定…DataNode:就是Slave,NameNode 下達命令,DataNode 執行實際的操作,
存盤實際的資料塊,執行資料塊的讀/寫操作, 提供真實檔案資料的存盤服務,
Data Node以資料塊的形式存盤HDFS檔案
典型的塊大小是64MB 盡量將資料塊分布到各個不同的DataNode節點上,Data Node 回應HDFS 客戶端進行讀寫請求
Data Node 周期性向NameNode匯報心跳資訊 / 資料塊資訊 / 快取資料塊資訊
DataNode節點的資料存盤目錄為/home/hduser/hadoop/dfs/data
(由:hdfs- -site. xml中的dfs.datanode.data.dir 屬性指定),Secondary NameNode:輔助 NameNode,分擔其作業量,
定期合并 fsimage和fsedits,并推送給NameNode,在緊急情況下,可輔助恢復 NameNode,
- 如果在NameNode上的資料損壞,HDFS中所有的檔案都不能被訪問
為了保證NameNode的高可用性,Hadoop對NameNode進行了補充Secondary NameNode- 相當于NameNode的快照能夠周期性地備份NameNode記錄NameNode中的元資料等,
也可以用來恢復NameNode,但SecondaryNameNode中的備份會滯后于NameNode. 所以會帶來一定的資料損失,
為了防止宕機.通常是將Secondary NameNode 和NameNode 設定為不同的主機,- 有點類似于, 老大的助手:
前線在戰斗, 司令并不能實時了解情況, 經常有助理講前選的最新資料報告老大
老大把舊資料 和 新資料 合并就是整個戰爭的情報資料 !
HDFS的副本機制和機架感知
HDFS 檔案副本機制
- 一個檔案有可能大于集群中任意一個磁盤,引入塊機制,可以很好的解決這個問題
- 使用塊作為檔案存盤的邏輯單位可以簡化存盤子系統
- 塊非常適合用于資料備份進而提供資料容錯能力
在Hadoop1當中, 檔案的 block 塊默認大小是 64M,Hadoop2當中, 檔案的 block 塊大小默認是128M,
block 塊的大小可以通過hdfs-site.xml當中的組態檔進行指定:
<property>
<name>dfs.block.size</name>
<value>塊大小 以位元組為單位</value>
</property>
機架感知
HDFS分布式檔案系統的內部有一個副本存放策略:以默認的副本數=3為例:
1、第一個副本塊存本機
2、第二個副本塊存跟本機同機架內的其他服務器節點
3、第三個副本塊存不同機架的一個服務器節點上
Master/Slave 架構
一個HDFS 集群, 由一個 NameNode 和多個 DataNode 組成, 屬于典型的Master/Stave模式;
資料讀流程:
由客戶端向Namelote請求訪問某個檔案,
Namelede 回傳該檔案所在位置即在哪個DataNode.上, 然后 由客戶端從該DataNode讀取資料,
資料寫流程:
由客戶端向NameNode發出檔案寫請求NameNode告訴客戶該向哪個DataNode寫入該檔案,
然后由客戶將檔案寫入該DataNode節點,隨后該DataNode將該檔案自動復制到其他DataNode節點上,默認三份備份,
Hadoop FS Shell 命令:
語法:
Hadoop fs < args>
其中hadoop: , 命令位于SHADOOP_HOME /bin目錄下
fs: 為其引數,表示FS Shell
< args>: 是fs的子命令,格式類似于Linux Shell 命令,并且功能也類似,如下:
- 創建目錄:mkdir
串列檔案:ls
查看檔案:cat
轉移檔案:put、get、mv、cp
洗掉檔案:rm、rmr
管理命令:test、du、expunge
使用 FS Shell 命令, 操作HDFS
HDFS 可以在這里查看, 當前實作要啟動 NameNode DataNode … start-all.sh

查看檔案系統
查看所有檔案
hadoop fs -ls /:后面指定要查詢檔案系統的目錄~
>Hadoop 也可以訪問本地目錄:個人覺得沒啥,直接用linux 自己的命令不香嗎?
對要訪問本地的檔案目錄前加上file://前綴
hadoop fs -ls file:///指定本地檔案訪問
或 Linuxls 目錄進行直接訪問!
一般主要使用hadoop fs命令來操作HDFS檔案系統!
創建目錄:接受路徑指定的URI作為引數,創建這些目錄
不支持支持同時創建多級目錄, 使用-p引數可以遞回創建目錄
Hadoop fs [-p] -mkdir 檔案名
# 在檔案系統根目錄下創建 user目錄
hadoop fs -mkdir /user
# 在HDFS中創建“/user/hadoop”目錄,前提需要有 /user
hadoop fs -mkdir /user/hadoop
# 同時創建多個目錄,"空格" 分隔區分,創建多個檔案目錄;
hadoop fs -mkdir /user/hadoop/dir1 /user/hadoop/dir2
查看檔案 cat
指定查看檔案路徑, 當然前提 HDFS中要有該檔案!
hadoop fs -cat URI [URI…]
# 查看HDFS檔案“file1.txt”和“file2.txt”
hadoop fs -cat /input2/file1.txt /input2/file2.txt
# 查看本地系統檔案“file3.txt”
hadoop fs -cat file:///home/hduser/file3.txt
轉移檔案 put ,get, mv, cp
put: 對應上傳
從本地檔案系統中復制單個或多個檔案到HDFS
hadoop fs -put 本地檔案1 本地檔案2 ... HDFS目錄
hadoop fs -moveFromLocal 本地檔案 HDFS目錄
和put命令類似,但是源檔案localsrc拷貝之后自身被洗掉
# 將本地 /home/hduser/file/file1.txt 檔案復制到HDFS目錄“/input2”
hadoop fs -put /home/hduser/file/file1.txt /input2
# 將多個本地檔案復制到HDFS目錄“/input2”
hadoop fs -put /home/hduser/file/file1.txt /home/hduser/file/file2.txt /input2
get:對應下載
復制HDFS檔案到本地檔案系統,是put的逆操作
hadoop fs -get HDFS上檔案 指定存放的本地目錄
# 將HDFS檔案“/input2/file1”復制到本地檔案系統“$HOME/file”中
hadoop fs -get /input2/file1 $HOME/file
mv:
將hdfs上的檔案從原路徑移動到目標路徑(移動之后檔案洗掉),該命令不能夸檔案系統;
hadoop fs -mv 檔案1 檔案2 ... 移動目錄
# 將HDFS上的file1.txt、file2.txt移動到dir1中
hadoop fs -mv /input2/file1.txt /input2/file2.txt /user/hadoop/dir1
cp:
將檔案從源路徑復制到目標路徑
-f 選項將覆寫目標,如果它已經存在,
-p 選項將保留檔案屬性(時間戳、所有權、許可、ACL、XAttr),
hadoop fs -cp 本地檔案1 本地檔案2 ... HDFS目錄
# 在HDFS中復制多個檔案到“/user/hadoop/dir1”
hadoop fs -cp /input2/file1.txt /input2/file2.txt /user/hadoop/dir1
# 在本地檔案系統中復制多個檔案到目錄“/tmp”
hadoop fs -cp file:///file1.txt file:///file2.txt file:///tmp
洗掉檔案 rm , rmr
洗掉指定的檔案,只洗掉非空目錄和檔案
hadoop fs -rm 非空目錄和檔案
rm的遞回版本,整個檔案夾及子檔案夾將全部洗掉
hadoop fs -rmr 非空目錄和檔案
# 洗掉非空檔案“/intpu2/file1.txt”
hadoop fs -rm /intpu2/file1.txt
# 遞回洗掉“/user/hadoop/dir1”
hadoop fs -rmr /user/hadoop/dir1
檢查 Test
hadoop fs -test -[選項] 檔案/目錄
-e:檢查檔案是否存在,如果存在則回傳0
-z:檢查檔案是否0位元組,如果是則回傳0
-d:檢查路徑是否為目錄,如果是則回傳1,否則回傳0
檢測檔案/目錄大小 du
hadoop fs -du 檔案/目錄
# 顯示檔案大小,如果是目錄則列出所有檔案,及其大小
hadoop fs -du /input2
清慷訓收站
hadoop fs -expunge
HDFS 的 Java API操作:
配置Windows下Hadoop環境
以上呢, 都是直接在 Linux 上的 Hadoop 中, 直接使用命令列形式操作HDFS;
然而, 這一定不是常用的, 這種操作一般都是在運維時候適合使用的方式:
實際開發中, 都是以Java代碼的形式來操作 Hadoop HDFS;
接下來介紹, 如何在Windows中使用Java來操作 HDFS:(首先還要對windows環境進行配置)
在windows系統需要配置hadoop運行環境,否則直接運行代碼會出現以下問題:
缺少winutils.exe
Could not locate executable null \bin\winutils.exe in the hadoop binaries
缺少hadoop.dll
Unable to load native-hadoop library for your platform… using builtin-Java classes where applicable
步驟:
第一步:
將hadoop2.7.5(或是其它版本的Hadoop) 檔案夾拷貝到一個沒有中文沒有空格的路徑下;
第二步:
在windows上面配置hadoop的環境變數:
HADOOP_HOME變數值:hadoop的安裝路徑,并將%HADOOP_HOME%\bin添加到path中
第三步:
把hadoop2.7.5檔案夾中bin目錄下的hadoop.dll檔案放到系統盤:C:\Windows\System32 目錄下
第四步:關閉windows重啟(重啟電腦!)
ok, 到這兒windows 就可以操作! Hadoop了!
Java操作 HDFS: 涉及的主要類
操作步驟:
使用FileSystem API編程步驟
獲取Configuration物件
獲取檔案系統的實體FileSystem物件
使用FileSystem物件操作檔案…
涉及的主要類
Configuration
- 該類的物件封轉了客戶端或者服務器的配置
conf.set(); 設定的屬性優先級要更高!,如果組態檔中指定的屬性與set(); 重復則使用 set(); 滴!FileSystem
- 該類的物件是一個
檔案系統物件,
可以用該物件的一些方法來對檔案進行操作, 可以通過:FileSystem 類的靜態方法 get();獲得該物件- get 方法從 conf 中的一個引數 fs.defaultFS 的配置值判斷具體是什么型別的檔案系統
- 如果我們的代碼中沒有指定 fs.defaultFS , 并且工程 ClassPath 下也沒有給定
相應的配置, conf 中的默認值就來自于 Hadoop 的 Jar 包中的 core-default.xml- 默認值為 file:/// , 則獲取的不是一個 DistributedFileSystem 的實體, 而是一個本地檔案系統的客戶端物件
獲取 FileSystem 的幾種方式
File Ststem類提供兩個靜態方法獲取 FileSystem檔案系統實體:
public static FileSystem get(Configuration conf)
public static FileSystem get(URI uri,Configuration conf)
前者由conf決定,也就是由 core- site.xml 中的fs.defautFS 決定回傳哪個檔案系統的實體
而后者以指定的URI方案為準,將忽略 fs.defautFfs 屬性,
第一種方式:普通Configuration set()方式不指定用戶
public void getFileSystem1() throws IOException {
Configuration configuration = new Configuration();
//指定我們使用的檔案系統型別:
//set(); 會覆寫原來定義好組態檔的屬性值...(關于組態檔可以參考上一篇博客~)
//hdfs://192.168.1.110:9000 這里填寫自己本機的訪問!!
configuration.set("fs.defaultFS", "hdfs://192.168.1.110:9000");
//獲取指定的檔案系統
FileSystem fileSystem = FileSystem.get(configuration);
System.out.println(fileSystem.toString());
//...正式操作
}
第二種方式:new Configuration() FileSystem指定檔案系統訪問埠
public void getFileSystem2() throws Exception{
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.1.110:9000"),
new Configuration());
System.out.println("fileSystem:"+fileSystem);
//...正式操作
}
第三種方式:指定操作用戶, 常用對于創建操作必須要用!
public void getFileSystem2() throws Exception{
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.1.110:9000"),new Configuration(),"root");
System.out.println("fileSystem:"+fileSystem);
//...正式操作
}
所用的Jar包 Maven坐標..
Maven超詳細教程 Maven可以借鑒this
Maven坐標庫:
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>2.7.5</version>
</dependency>
</dependencies>
Java常用操作 HDFS:
下載: 從HDFS上下載檔案到,Windows本地…
import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
public class Hadoop {
//下載: 從HDFS上下載檔案到,Windows本地...
public static void downLoad() throws Exception {
//創建 Configuration FileSystem
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://192.168.1.110:9000");
FileSystem fileSystem = FileSystem.get(conf);
//new Path(); 表示HDFS檔案系統上的路徑;
InputStream is = fileSystem.open(new Path("/user/abc.txt"));
//造檔案,要事先確保本地有檔案才往里面寫檔案呀~
File ff = new File("D:/abc.txt");
FileOutputStream os = new FileOutputStream(ff); //創建寫入流~
//Hadoop 提供的IOUtils
//可以在輸入流out(讀) 輸出流input(寫) 復制資料,由hadoop-common..jar提供!
IOUtils.copy(is, os);
//關閉資源
os.close();
is.close();
}
public static void main(String[] args) {
try {
downLoad();
} catch (Exception e) {
e.printStackTrace();
}
}
}
查看HDFS檔案串列
import org.apache.hadoop.conf.Configuration;
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 java.net.URI;
public class Hadoop {
//查看HDFS檔案串列
public static void fileList() throws Exception {
//創建 Configuration FileSystem 對于一些檔案需要訪問權限需要指定一個用戶...
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.1.110:9000"),new Configuration(),"root");
System.out.println("fileSystem:"+fileSystem);
//fileSystem.listFiles:根據HDFS目錄,回傳目錄下File陣列;
//new Path(); 表示HDFS檔案系統上的路徑; true:表示目錄包含子目錄~
RemoteIterator<LocatedFileStatus> it = fileSystem.listFiles(new Path("/"), true);
//回圈列印檔案名;
while (it.hasNext()) {
LocatedFileStatus next = it.next();
System.out.println(next.getPath().toString());
}
//關閉檔案系統
fileSystem.close();
}
public static void main(String[] args) {
try {
fileList();
} catch (Exception e) {
e.printStackTrace();
}
}
}
創建目錄并創建檔案
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.net.URI;
public class Hadoop {
public static void createDir() throws Exception {
//創建 Configuration FileSystem 對于一些檔案需要訪問權限 需要指定一個用戶...
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.1.110:9000"),new Configuration(),"root");
//fileSystem.mkdirs(..); 在HDFS 檔案系統上創建,檔案目錄...(支持層級創建~)
fileSystem.mkdirs(new Path("/hello/dir/test"));
//fileSystem.createNewFile(..); 在HDFS 檔案系統上創建,檔案;
fileSystem.createNewFile(new Path("/hello/dir/test/abc.txt"));
fileSystem.close();
}
public static void main(String[] args) {
try {
createDir();
} catch (Exception e) {
e.printStackTrace();
}
}
}
拷貝 或 上傳: [本地]檔案;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.net.URI;
public class Hadoop {
//拷貝 或 上傳: [本地]檔案;
public static void upload() throws Exception {
//創建 Configuration FileSystem 對于一些檔案需要訪問權限 需要指定一個用戶...
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.1.110:9000"),new Configuration(),"root");
//fileSystem.copyFromLocalFile(); 拷貝本地檔案到 HDFS那里去~ 當然 檔案要事先存在! 目錄存在則上傳檔案,不存在會自動創建!
fileSystem.copyFromLocalFile(new Path("D://abc.txt"), new Path("/hello/dir/"));
fileSystem.close();
}
public static void main(String[] args) {
try {
upload();
} catch (Exception e) {
e.printStackTrace();
}
}
}
洗掉HDFS 檔案/目錄結構;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.net.URI;
public class Hadoop {
public static void delete() throws Exception {
//創建 Configuration FileSystem 對于一些檔案需要訪問權限 需要指定一個用戶...
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.1.110:9000"),new Configuration(),"root");
//fileSystem.delete(); 洗掉指定目錄/檔案 true包含子目錄結構洗掉!
fileSystem.delete(new Path("/hello/dir/"), true); //洗掉HDFS上, hello目錄下 dir目錄結構;
fileSystem.close();
}
public static void main(String[] args) {
try {
delete();
} catch (Exception e) {
e.printStackTrace();
}
}
}
檔案查詢 getFileStatus( path p);
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.net.URI;
public class Hadoop {
public static void selFlie() throws Exception {
//創建 Configuration FileSystem 對于一些檔案需要訪問權限 需要指定一個用戶...
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.1.110:9000"),new Configuration(),"root");
//getFileLinkStatus(path p); 回傳一個檔案物件;
FileStatus stat = fileSystem.getFileLinkStatus(new Path("/user"));
System.out.println("檔案路徑:"+stat.getPath());
System.out.println("檔案塊大小:"+stat.getBlockSize());
System.out.println("檔案大小:"+stat.getLen());
System.out.println("副本數量:"+stat.getReplication());
System.out.println("用戶:"+stat.getOwner()) ;
System.out.println ("用戶組:"+stat.getGroup());
System.out.println("權限:"+stat.getPermission().toString());
fileSystem.close();
}
public static void main(String[] args) {
try {
selFlie();
} catch (Exception e) {
e.printStackTrace();
}
}
}
多檔案合并 并寫入檔案HDFS中!
import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import java.net.URI;
public class Hadoop {
public static void bigFile() throws Exception {
//創建 Configuration FileSystem 對于一些檔案需要訪問權限 需要指定一個用戶...
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.1.110:9000"),new Configuration(),"root");
//在檔案系統上創建一個檔案,存盤小檔案的 大檔案
FSDataOutputStream os = fileSystem.create(new Path("/bigFile.txt"));
//獲取本地物件
LocalFileSystem local = FileSystem.getLocal(new Configuration());
//獲取本地的檔案串列
FileStatus[] fileStatuses = local.listStatus(new Path("D:\\out"));
for (FileStatus fileStatus : fileStatuses) {
//獲取第I個檔案輸入物件
FSDataInputStream is = local.open(fileStatus.getPath());
//將讀取的檔案寫入到大檔案中
IOUtils.copy(is, os);
//每次結束并關閉資源!
IOUtils.closeQuietly(is);
}
IOUtils.closeQuietly(os);
fileSystem.close();
}
public static void main(String[] args) {
try {
bigFile();
} catch (Exception e) {
e.printStackTrace();
}
}
}
到這里, 基本的步驟就是如此了…歡迎后面學習, 建議一建三連呀!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/240978.html
標籤:其他






