之前,一直通過Linux命令操作HDFS恨诱。接下來(lái),在本地配置HDFS客戶端室叉,通過編寫代碼操作HDFS。
環(huán)境:
- mbp2018
- hadoop-2.7.7
配置步驟
1. 在本地解壓hadoop-2.7.7.tar.gz硫惕,并配置環(huán)境變量茧痕。在終端輸入$ hadoop
測(cè)試是否安裝成功。
2. 在IDEA中建立一個(gè)空的mavean工程恼除。
File new Projects
一路確定即可
3. 打開工程中的pox.xml文件踪旷,在pom.xml文件中加入如下內(nèi)容:
<?xml version="1.0" encoding="UTF-8"?>
<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.bigdata</groupId>
<artifactId>hadoop100</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.7</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.7</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.7</version>
</dependency>
</dependencies>
</project>
聯(lián)網(wǎng)后,等待所有依賴導(dǎo)入完成豁辉。導(dǎo)入成功的包顏色會(huì)是白的令野,否則應(yīng)該是灰色或者黃色。
4. 在工程的resources目錄中加入log4j.properties文件徽级,并寫入如下內(nèi)容:
log4j.rootLogger=INFO,stdout,debug,error
#輸出到控制臺(tái)
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %p [%t] %C.%M(%L) | %m%n
#輸出DEBUG級(jí)別以上的日志到文件
log4j.appender.debug=org.apache.log4j.DailyRollingFileAppender
log4j.appender.debug.layout=org.apache.log4j.PatternLayout
log4j.appender.debug.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %p [%t] %C.%M(%L) | %m%n
log4j.appender.debug.File=./logs/debug.txt
log4j.appender.debug.DatePattern=','yyyy-MM-dd
log4j.appender.debug.Threshold=DEBUG
log4j.appender.debug.Append=true
log4j.appender.debug.Encoding=UTF-8
#輸出DEBUG級(jí)別以上的日志到文件
log4j.appender.error=org.apache.log4j.DailyRollingFileAppender
log4j.appender.error.layout=org.apache.log4j.PatternLayout
log4j.appender.error.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %p [%t] %C.%M(%L) | %m%n
log4j.appender.error.File=./logs/error.txt
log4j.appender.error.DatePattern=','yyyy-MM-dd
log4j.appender.error.Threshold=ERROR
log4j.appender.error.Append=true
log4j.appender.error.Encoding=UTF-8
5. 新建一個(gè)JavaClass文件气破,準(zhǔn)備測(cè)試客戶端是否創(chuàng)建成功
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.junit.Test;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class HDFSClient {
public FileSystem getConf(){
Configuration conf = new Configuration();
FileSystem fs = null;
try {
fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), conf, "lg"); // 以用戶lg連接hdfs://hadoop102:9000,因?yàn)镹ameNode在hadoop102上
}catch (Exception e){
System.out.println(e);
}
return fs;
}
public static void main(String[] args) throws IOException, URISyntaxException, InterruptedException {
// 1 獲取客戶端
FileSystem fs = getConf();
// 2 在hdfs上創(chuàng)建路徑
fs.mkdirs(new Path("/school"));
// 3 關(guān)閉資源
fs.close();
System.out.println("over");
}
在瀏覽器中輸入http://hadoop102:9000查看根目錄下是否有school目錄餐抢。
注意:
- 在連接前现使,首先需要配置本機(jī)的hosts文件,即主機(jī)名和ip的映射關(guān)系
- 在連接hadoop102時(shí)旷痕,相當(dāng)于使用lg用戶登錄hadoop102節(jié)點(diǎn)碳锈,所以需要配置本機(jī)和hadoop102之間的SSH免密登錄。
HDFS客戶端的常用操作
1. 上傳文件
// 1 文件上傳
@Test
public void testCopyFromLocalFile() throws IOException {
// 1 獲取fs對(duì)象
FileSystem fs = getConf();
// 2 執(zhí)行上傳API
fs.copyFromLocalFile(new Path(filePath), new Path("/xianzhang.txt"));
// 3 關(guān)閉fs對(duì)象
fs.close();
}
2. 下載文件
// 2 下載文件
@Test
public void testCopyTOLocalFile() throws IOException {
// 1 獲取fs對(duì)象
FileSystem fs = getConf();
// 2 執(zhí)行下載操作
fs.copyToLocalFile(new Path("/school/xianzhang.txt"), new Path(filePath + "/xianzhang.txt"));
// 3 關(guān)閉資源
fs.close();
}
3. 刪除文件
// 3 文件刪除
@Test
public void testDelete() throws IOException {
FileSystem fs = getConf();
fs.delete(new Path("/school"), true);
fs.close();
}
4. 文件更名
// 4 文件更名
@Test
public void testRename() throws IOException {
FileSystem fs = getConf();
fs.rename(new Path("/xianzhang.txt"), new Path("/shizhang.txt"));
fs.close();
}
5. 查看文件詳情
// 5 查看文件詳情
@Test
public void testListFile() throws IOException {
FileSystem fs = getConf();
// 查看文件詳情
RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);
while(listFiles.hasNext()) {
LocatedFileStatus fileStatus = listFiles.next();
System.out.println(fileStatus.getPath().getName()); // 文件名
System.out.println(fileStatus.getPermission()); // 權(quán)限
System.out.println(fileStatus.getLen()); // 長(zhǎng)度
BlockLocation[] blockLocations = fileStatus.getBlockLocations();
for (BlockLocation blockLocation : blockLocations) {
String[] hosts = blockLocation.getHosts();
for (String host : hosts) {
System.out.println(host);
}
}
System.out.println("---------------------------");
}
fs.close();
}
6. 判斷文件類型
// 6 判斷是文件還是文件夾
@Test
public void testListType() throws IOException {
FileSystem fs = getConf();
// 判斷操作
FileStatus[] listStatus = fs.listStatus(new Path("/"));
for (FileStatus fileStatus : listStatus) {
if (fileStatus.isFile()) {
System.out.println("f:" + fileStatus.getPath().getName()); // 文件
} else {
System.out.println("d:" + fileStatus.getPath().getName()); // 目錄
}
}
fs.close();
}