这里写目录标题
- 1、环境准备
- 2、代码实现
- 3 、项目地址
1、环境准备
1、HDFS环境搭建:javascript:void(0) 2、SpringBoot 2.1.1版本;
2、代码实现
1、pom.xml文件
<?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.ljl</groupId>
<artifactId>hadoop_test</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<!-- Add typical dependencies for a web application -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.41</version>
</dependency>
<!-- hadoop-->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>3.1.1</version>
</dependency>
<!--swagger测试后台接口-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!--为解决hadoop中与swagger中的 guava 冲突而加-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
</dependency>
<!-- Package as an executable jar -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、application.yml 文件
server:
port: 8083
spring:
application:
name: hadoopDemo
servlet:
multipart:
max-file-size: 1GB
max-request-size: 1GB
3、application.properties 文件
hdfs.path=hdfs://192.168.249.133:9000
4、HDFS配置类
package com.ljl.hadoopconf;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* @author :
* @date :Created in 2019/11/5 11:32
* @description:
* @modified By:
* @version:
*/
@Configuration
public class HDFSConf {
@Value("${hdfs.path}")
private String path;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}
5、HDFSService类
package com.ljl.hadoopconf;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
* @author :
* @date :Created in 2019/11/5 13:02
* @description:
* @modified By:
* @version:
*/
@Service
public class HdfsService {
@Value("${hdfs.path}")
private String path;
// @Value("${hdfs.username}")
// private String username;
private static String hdfsPath;
private static String hdfsName;
private static final int bufferSize = 1024 * 1024 * 64;
/**
* 获取HDFS配置信息
* @return
*/
private static Configuration getConfiguration() {
Configuration configuration = new Configuration();
configuration.set("fs.defaultFS", hdfsPath);
return configuration;
}
/**
* 获取HDFS文件系统对象
* @return
* @throws Exception
*/
public static FileSystem getFileSystem() throws Exception {
// 客户端去操作hdfs时是有一个用户身份的,默认情况下hdfs客户端api会从jvm中获取一个参数作为自己的用户身份
// DHADOOP_USER_NAME=hadoop
// 也可以在构造客户端fs对象时,通过参数传递进去
FileSystem fileSystem = FileSystem.get(new URI(hdfsPath), getConfiguration(), hdfsName);
return fileSystem;
}
/**
* 在HDFS创建文件夹
* @param path
* @return
* @throws Exception
*/
public static boolean mkdir(String path) throws Exception {
if (StringUtils.isEmpty(path)) {
return false;
}
if (existFile(path)) {
return true;
}
FileSystem fs = getFileSystem();
// 目标路径
Path srcPath = new Path(path);
boolean isOk = fs.mkdirs(srcPath);
fs.close();
return isOk;
}
/**
* 判断HDFS文件是否存在
* @param path
* @return
* @throws Exception
*/
public static boolean existFile(String path) throws Exception {
if (StringUtils.isEmpty(path)) {
return false;
}
FileSystem fs = getFileSystem();
Path srcPath = new Path(path);
boolean isExists = fs.exists(srcPath);
return isExists;
}
/**
* 读取HDFS目录信息
* @param path
* @return
* @throws Exception
*/
public static List<Map<String, Object>> readPathInfo(String path) throws Exception {
if (StringUtils.isEmpty(path)) {
return null;
}
if (!existFile(path)) {
return null;
}
FileSystem fs = getFileSystem();
// 目标路径
Path newPath = new Path(path);
FileStatus[] statusList = fs.listStatus(newPath);
List<Map<String, Object>> list = new ArrayList<>();
if (null != statusList && statusList.length > 0) {
for (FileStatus fileStatus : statusList) {
Map<String, Object> map = new HashMap<>();
map.put("filePath", fileStatus.getPath());
map.put("fileStatus", fileStatus.toString());
list.add(map);
}
return list;
} else {
return null;
}
}
/**
* 用流将文件写入HDFS
* @param path HDFS上的路径
* @param file 文件
* @throws Exception
*/
public static void writFileInHDFS(String path, MultipartFile file) throws Exception {
if (StringUtils.isEmpty(path) || null == file.getBytes()) {
return;
}
FileSystem fs = getFileSystem();
Path newPath = new Path(path);
// 打开一个输出流
FSDataOutputStream outputStream = fs.create(newPath);
outputStream.write(file.getBytes());
outputStream.close();
fs.close();
}
/**
* 读取HDFS文件内容
* @param path
* @return
* @throws Exception
*/
public static String readFile(String path) throws Exception {
if (StringUtils.isEmpty(path)) {
return null;
}
if (!existFile(path)) {
return null;
}
FileSystem fs = getFileSystem();
// 目标路径
Path srcPath = new Path(path);
FSDataInputStream inputStream = null;
try {
inputStream = fs.open(srcPath);
// 防止中文乱码
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String lineTxt = "";
StringBuffer sb = new StringBuffer();
while ((lineTxt = reader.readLine()) != null) {
sb.append(lineTxt);
}
return sb.toString();
} finally {
inputStream.close();
fs.close();
}
}
/**
* 读取HDFS文件列表
* @param path
* @return
* @throws Exception
*/
public static List<Map<String, String>> listFile(String path) throws Exception {
if (StringUtils.isEmpty(path)) {
return null;
}
if (!existFile(path)) {
return null;
}
FileSystem fs = getFileSystem();
// 目标路径
Path srcPath = new Path(path);
// 递归找到所有文件
RemoteIterator<LocatedFileStatus> filesList = fs.listFiles(srcPath, true);
List<Map<String, String>> returnList = new ArrayList<>();
while (filesList.hasNext()) {
LocatedFileStatus next = filesList.next();
String fileName = next.getPath().getName();
Path filePath = next.getPath();
Map<String, String> map = new HashMap<>();
map.put("fileName", fileName);
map.put("filePath", filePath.toString());
returnList.add(map);
}
fs.close();
return returnList;
}
/**
* HDFS重命名文件
* @param oldName
* @param newName
* @return
* @throws Exception
*/
public static boolean renameFile(String oldName, String newName) throws Exception {
if (StringUtils.isEmpty(oldName) || StringUtils.isEmpty(newName)) {
return false;
}
FileSystem fs = getFileSystem();
// 原文件目标路径
Path oldPath = new Path(oldName);
// 重命名目标路径
Path newPath = new Path(newName);
boolean isOk = fs.rename(oldPath, newPath);
fs.close();
return isOk;
}
/**
* 删除HDFS文件
* @param path
* @return
* @throws Exception
*/
public static boolean deleteFile(String path) throws Exception {
if (StringUtils.isEmpty(path)) {
return false;
}
if (!existFile(path)) {
return false;
}
FileSystem fs = getFileSystem();
Path srcPath = new Path(path);
boolean isOk = fs.deleteOnExit(srcPath);
fs.close();
return isOk;
}
/**
* 上传HDFS文件
* @param path
* @param uploadPath
* @throws Exception
*/
public static void uploadFile(String path, String uploadPath) throws Exception {
if (StringUtils.isEmpty(path) || StringUtils.isEmpty(uploadPath)) {
return;
}
FileSystem fs = getFileSystem();
// 上传路径
Path clientPath = new Path(path);
// 目标路径
Path serverPath = new Path(uploadPath);
// 调用文件系统的文件复制方法,第一个参数是否删除原文件true为删除,默认为false
fs.copyFromLocalFile(true, clientPath, serverPath);
fs.close();
}
/**
* 下载HDFS文件
* @param path
* @param downloadPath
* @throws Exception
*/
public static void downloadFile(String path, String downloadPath) throws Exception {
if (StringUtils.isEmpty(path) || StringUtils.isEmpty(downloadPath)) {
return;
}
FileSystem fs = getFileSystem();
// 上传路径
Path clientPath = new Path(path);
// 目标路径
Path serverPath = new Path(downloadPath);
// 调用文件系统的文件复制方法,第一个参数是否删除原文件true为删除,默认为false
fs.copyToLocalFile(false, clientPath, serverPath);
fs.close();
}
/**
* HDFS文件复制
* @param sourcePath
* @param targetPath
* @throws Exception
*/
public static void copyFile(String sourcePath, String targetPath) throws Exception {
if (StringUtils.isEmpty(sourcePath) || StringUtils.isEmpty(targetPath)) {
return;
}
FileSystem fs = getFileSystem();
// 原始文件路径
Path oldPath = new Path(sourcePath);
// 目标路径
Path newPath = new Path(targetPath);
FSDataInputStream inputStream = null;
FSDataOutputStream outputStream = null;
try {
inputStream = fs.open(oldPath);
outputStream = fs.create(newPath);
IOUtils.copyBytes(inputStream, outputStream, bufferSize, false);
} finally {
inputStream.close();
outputStream.close();
fs.close();
}
}
/**
* 打开HDFS上的文件并返回byte数组
* @param path
* @return
* @throws Exception
*/
public static byte[] openFileToBytes(String path) throws Exception {
if (StringUtils.isEmpty(path)) {
return null;
}
if (!existFile(path)) {
return null;
}
FileSystem fs = getFileSystem();
// 目标路径
Path srcPath = new Path(path);
try {
FSDataInputStream inputStream = fs.open(srcPath);
return IOUtils.readFullyToByteArray(inputStream);
} finally {
fs.close();
}
}
/**
* 获取某个文件在HDFS的集群位置
* @param path
* @return
* @throws Exception
*/
public static BlockLocation[] getFileBlockLocations(String path) throws Exception {
if (StringUtils.isEmpty(path)) {
return null;
}
if (!existFile(path)) {
return null;
}
FileSystem fs = getFileSystem();
// 目标路径
Path srcPath = new Path(path);
FileStatus fileStatus = fs.getFileStatus(srcPath);
return fs.getFileBlockLocations(fileStatus, 0, fileStatus.getLen());
}
@PostConstruct
public void getPath() {
hdfsPath = this.path;
}
}
5、controller 类
package com.ljl.controller;
import com.alibaba.fastjson.JSONObject;
import com.ljl.hadoopconf.HdfsService;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.fs.BlockLocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.List;
import java.util.Map;
/**
* 已经全部测试均可用
* @author :
* @date :Created in 2019/11/7 15:25
* @description:
* @modified By:
* @version:
*/
@RestController
@RequestMapping("/hadoop")
public class DemoController {
private static Logger LOGGER = LoggerFactory.getLogger(DemoController.class);
/**
* 创建文件夹
* @param path
* @return
* @throws Exception
*/
@RequestMapping(value = "mkdir", method = RequestMethod.POST)
@ResponseBody
public JSONObject mkdir(@RequestParam("path") String path) throws Exception {
JSONObject object = new JSONObject( );
if (StringUtils.isEmpty(path)) {
object.put("message", "请求参数为空");
LOGGER.debug("请求参数为空");
return object;
}
// 创建空文件夹
boolean isOk = HdfsService.mkdir(path);
if (isOk) {
LOGGER.debug("文件夹创建成功");
object.put("message", "文件夹创建成功");
return object;
} else {
LOGGER.debug("文件夹创建失败");
object.put("message", "文件夹创建成功");
return object;
}
}
/**
* 读取HDFS目录信息
* @param path
* @return
* @throws Exception
*/
@PostMapping("/readPathInfo")
public JSONObject readPathInfo(@RequestParam("path") String path) throws Exception {
List<Map<String, Object>> list = HdfsService.readPathInfo(path);
JSONObject object = new JSONObject( );
object.put( "读取HDFS目录信息成功", list);
return object;
}
/**
* 读取HDFS文件内容
* @param path hdfs上路径
* @return
* @throws Exception
*/
@PostMapping("/readFile")
public JSONObject readFile(@RequestParam("path") String path) throws Exception {
JSONObject object = new JSONObject( );
String targetPath = HdfsService.readFile(path);
object.put("message", "读取HDFS文件内容success");
object.put("data",targetPath);
return object;
}
/**
* 读取文件列表
* @param path hdfs上路径
* @return
* @throws Exception
*/
@PostMapping("/listFile")
public JSONObject listFile(@RequestParam("path") String path) throws Exception {
JSONObject object = new JSONObject( );
if (StringUtils.isEmpty(path)) {
object.put("message","请求参数为空");
return object;
}
List<Map<String, String>> returnList = HdfsService.listFile(path);
object.put("message","读取文件列表成功");
object.put("data",returnList);
return object;
}
/**
* 重命名文件
* @param oldName
* @param newName
* @return
* @throws Exception
*/
@PostMapping("/renameFile")
public JSONObject renameFile(@RequestParam("oldName") String oldName, @RequestParam("newName") String newName)
throws Exception {
JSONObject object = new JSONObject( );
if (StringUtils.isEmpty(oldName) || StringUtils.isEmpty(newName)) {
object.put("message","请求参数为空");
return object;
}
boolean isOk = HdfsService.renameFile(oldName, newName);
if (isOk) {
object.put("message","文件重命名成功");
return object;
} else {
object.put("message","文件重命名失败");
return object;
}
}
/**
* 删除文件
* @param path hdfs 上的路径
* @return
* @throws Exception
*/
@PostMapping("/deleteFile")
public JSONObject deleteFile(@RequestParam("path") String path) throws Exception {
JSONObject object = new JSONObject( );
boolean isOk = HdfsService.deleteFile(path);
if (isOk) {
object.put("message","delete file success");
return object;
} else {
object.put("message","delete file fail");
return object;
}
}
/**
* 上传文件
* @param path 本地文件路径
* @param uploadPath hdfs上路径
* @return
* @throws Exception
*/
@PostMapping("/uploadFile")
public String uploadFile(@RequestParam("path") String path, @RequestParam("uploadPath") String uploadPath)
throws Exception {
HdfsService.uploadFile(path, uploadPath);
return "upload file success" ;
}
/**
* 下载文件
* @param path 目标路径
* @param downloadPath 源路径
* @return
* @throws Exception
*/
@PostMapping("/downloadFile")
public String downloadFile(@RequestParam("path") String path, @RequestParam("downloadPath") String downloadPath)
throws Exception {
HdfsService.downloadFile(path, downloadPath);
return "download file success" ;
}
/**
* HDFS文件复制
* @param sourcePath 源文件路径 例如:/user/Administrator/001/11.jpg
* @param targetPath 目标路径 例如:/user/Administrator/111/11.jpg
* @return
* @throws Exception
*/
@PostMapping("/copyFile")
public String copyFile(@RequestParam("sourcePath") String sourcePath, @RequestParam("targetPath") String targetPath)
throws Exception {
HdfsService.copyFile(sourcePath, targetPath);
return "copy file success" ;
}
/**
* 查看文件是否已存在
* @param path hdfs上文件路径
* @return
* @throws Exception
*/
@PostMapping("/existFile")
public String existFile(@RequestParam("path") String path) throws Exception {
boolean isExist = HdfsService.existFile(path);
return "file isExist: " + isExist ;
}
}
3 、项目地址
https://github.com/lijianleiGit/SpringBoot-HDFS