HDFS 設計的主要目的是對海量數據進行存儲,也就是說在其上能夠存儲很大量的文件。
HDFS 將這些文件分割之後,存儲在不同的 DataNode 上,HDFS 提供了通過Java API 對 HDFS 裏面的文件進行操作的功能,數據塊在 DataNode 上的存放位置,對於開發者來說是透明的。
使用 Java API 可以完成對 HDFS 的各種操作,如新建文件、刪除文件、讀取文件內容等。下面將介紹 HDFS 常用的 Java API 及其編程實例。
概念
- Configuration 封裝了客戶端或者服務器的配置
- FileSystem 文件系統對象,用該對象的方法來對文件進行操作
- FileStatus 用於向客戶端展示系統中文件和目錄的元數據
- FSDatalnputStream HDFS 中的輸入流,用於讀取 Hadoop 文件
- FSDataOutputStream HDFS 中的輸出流,用於寫 Hadoop 文件
- Path 用於表示 Hadoop 文件系統中的文件或者目錄的路徑
具體操作
- 1 導入maven依賴包
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>3.1.1</version>
</dependency>
- 2 初始化配置
Configuration conf;
FileSystem fileSystem;
public HdfsAPI() {
conf = new Configuration();
conf.set("dfs.replication", "2");
conf.set("dfs.blocksize", "128m");
try {
fileSystem = FileSystem.get(new URI("hdfs://${NameNode}:9000"), conf, "hadoop");
} catch (Exception e) {
e.printStackTrace();
}
}
- 3 get文件 get
public void testGet() throws IllegalArgumentException, IOException {
fileSystem.copyToLocalFile(new Path("/output/part.txt"), new Path("~/Downloads"));
fileSystem.close();
}
- 4 獲取文件信息 ls
public void testLs() throws IllegalArgumentException, IOException {
RemoteIterator<LocatedFileStatus> listFiles = fileSystem.listFiles(new Path("/"), true);
while (listFiles.hasNext()) {
LocatedFileStatus status = listFiles.next();
System.out.println("路徑:" + status.getPath());
System.out.println("塊大小:" + status.getBlockSize());
System.out.println("文件長度:" + status.getLen());
System.out.println("副本數:" + status.getReplication());
System.out.println("塊的位置信息:" + Arrays.toString(status.getBlockLocations()) + "\n");
}
fileSystem.close();
}
- 5 創建目錄,多級目錄 mkdir
public void testMkdir() throws IllegalArgumentException, IOException {
fileSystem.mkdirs(new Path("/output/test/testmk"));
fileSystem.close();
}
- 6 刪除文件,目錄 rm
public void testDeldir() throws IllegalArgumentException, IOException {
boolean delete = fileSystem.delete(new Path("/output/test/testmk"), true);
if (delete) {
System.out.println("文件已經刪除");
}
fileSystem.close();
}
- 7 讀取hdfs文件內容
public void testReadData() throws IOException {
FSDataInputStream in = fileSystem.open(new Path("/test.txt"));//hdfs自帶流打開文件
BufferedReader br = new BufferedReader(new InputStreamReader(in, "utf-8"));//讀入流並放在緩衝區
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
in.close();
br.close();
fileSystem.close();
}
- 8 讀取hdfs中文件中指定偏移的內容
public void testRandomReadData() throws IOException {
FSDataInputStream in = fileSystem.open(new Path("/test.txt"));
in.seek(12);//定位到12位置開始讀
byte[] buf = new byte[16];//往後讀取16個位
in.read(buf);//ba流讀到buf中
System.out.println(new String(buf));
in.close();
fileSystem.close();
}
- 9 數據寫到hdfs中
public void testWriteData() throws IOException {
FSDataOutputStream out = fileSystem.create(new Path("/yy.jpg"), false);
FileInputStream in = new FileInputStream("~/Download/wechatpic_20190309221605.jpg");
byte[] buf = new byte[1024];
int read = 0;
while ((read = in.read(buf)) != -1) {
out.write(buf, 0, read);
}
out.close();
fileSystem.close();
}