代码:
1.Hdfs
package com.boot.base.common.util.hdfs;
import com.boot.base.common.util.LogUtil;
import com.google.common.collect.Lists;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;
import java.io.*;
import java.net.URI;
import java.util.List;
public class Hdfs {
private final int HDFS_OUT_BUFF_SIZE = 1024*1024*4;
private FileSystem fs;
private final String url;
private final String userName;
public Hdfs(String url, String userName) {
this.url = url;
this.userName = userName;
}
public void open() {
try {
Configuration conf = new Configuration();
fs = FileSystem.get(new URI(url), conf, userName);
LogUtil.info("创建[Hadoop FileSystem]实例成功");
} catch (Exception e) {
LogUtil.error("创建[Hadoop FileSystem]实例失败", e);
}
}
public void close() {
try {
if (null != fs) {
fs.close();
LogUtil.info("关闭[Hadoop FileSystem]实例成功");
}
} catch(Exception e) {
LogUtil.error("关闭[Hadoop FileSystem]实例失败", e);
}
}
public boolean isConnected() throws IOException {
return fs.exists(new Path("/"));
}
public boolean exists(String path) throws IOException {
return fs.exists(new Path(path));
}
public Path getPath(String path) throws IOException {
return new Path(path);
}
public FileStatus getFileStatus(String path) throws IOException {
return fs.getFileStatus(new Path(path));
}
public FileStatus[] listFileStatus(String path) throws IOException {
return fs.listStatus(new Path(path));
}
public ContentSummary getContentSummary(String path) throws IOException {
ContentSummary contentSummary = null;
Path hdfsPath = new Path(path);
if (fs.exists(hdfsPath)) {
contentSummary = fs.getContentSummary(hdfsPath);
}
return contentSummary;
}
public List<String> listFileName() throws IOException {
List<String> res = Lists.newArrayList();
FileStatus[] fileStatuses = fs.listStatus(new Path("/"));
for (FileStatus fileStatus : fileStatuses){
res.add(fileStatus.getPath() +":类型--"+ (fileStatus.isDirectory()? "文件夹":"文件"));
}
return res;
}
public List<String> listFileName(String path) throws IOException {
List<String> res = Lists.newArrayList();
FileStatus[] fileStatuses = fs.listStatus(new Path(path));
for (FileStatus fileStatus : fileStatuses){
res.add(fileStatus.getPath().toUri().getPath());
}
return res;
}
public boolean deleteFile(String path) throws IOException {
return fs.delete(new Path(path), false);
}
public String uploadFileByStream(InputStream in, String path) throws Exception {
OutputStream os = fs.create(new Path(path));
IOUtils.copyBytes(in, os, HDFS_OUT_BUFF_SIZE, true);
return path;
}
public InputStream downloadFileByStream(String path) throws Exception {
return fs.open(new Path(path));
}
public InputStream downloadFileByStream(Path path) throws Exception {
return fs.open(path);
}
}
2.HdfsFactory
package com.boot.base.common.util.hdfs;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import java.io.IOException;
public class HdfsFactory implements PooledObjectFactory<Hdfs> {
private final String url;
private final String userName;
public HdfsFactory(String url, String userName){
this.url = url;
this.userName = userName;
}
@Override
public PooledObject<Hdfs> makeObject() throws Exception {
Hdfs hdfs = new Hdfs(url, userName);
hdfs.open();
return new DefaultPooledObject<Hdfs>(hdfs);
}
@Override
public void destroyObject(PooledObject<Hdfs> pooledObject) throws Exception {
Hdfs hdfs = pooledObject.getObject();
hdfs.close();
}
@Override
public boolean validateObject(PooledObject<Hdfs> pooledObject) {
Hdfs hdfs = pooledObject.getObject();
try {
return hdfs.isConnected();
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
@Override
public void activateObject(PooledObject<Hdfs> pooledObject) throws Exception {
}
@Override
public void passivateObject(PooledObject<Hdfs> pooledObject) throws Exception {
}
}
3.HdfsPoolConfig
package com.boot.base.config.hdfs;
import com.boot.base.common.util.hdfs.HdfsClient;
import com.boot.base.common.util.hdfs.HdfsFactory;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HdfsPoolConfig extends GenericObjectPoolConfig {
@Value("${hdfs.url}")
private String url;
@Value("${hdfs.userName}")
private String userName;
@Value("${hdfs.pool.maxTotal}")
private String maxTotal;
@Value("${hdfs.pool.maxIdle}")
private String maxIdle;
@Value("${hdfs.pool.minIdle}")
private String minIdle;
@Value("${hdfs.pool.maxWaitMillis}")
private String maxWaitMillis;
@Value("${hdfs.pool.minEvictableIdleTimeMillis}")
private String minEvictableIdleTimeMillis;
@Value("${hdfs.pool.timeBetweenEvictionRunsMillis}")
private String timeBetweenEvictionRunsMillis;
@Bean(initMethod = "init", destroyMethod = "stop")
public HdfsClient HdfsClient(){
HdfsClient client = new HdfsClient();
return client;
}
@Bean
public HdfsPoolConfig HdfsPoolConfig(){
HdfsPoolConfig hdfsPoolConfig = new HdfsPoolConfig();
hdfsPoolConfig.setMaxTotal(Integer.valueOf(maxTotal));
hdfsPoolConfig.setMaxIdle(Integer.valueOf(maxIdle));
hdfsPoolConfig.setMinIdle(Integer.valueOf(minIdle));
hdfsPoolConfig.setMaxWaitMillis(Long.parseLong(maxWaitMillis));
hdfsPoolConfig.setMinEvictableIdleTimeMillis(Long.parseLong(minEvictableIdleTimeMillis));
hdfsPoolConfig.setTimeBetweenEvictionRunsMillis(Long.parseLong(timeBetweenEvictionRunsMillis));
return hdfsPoolConfig;
}
@Bean
public HdfsFactory HdfsFactory(){
return new HdfsFactory(url, userName);
}
}
4.HdfsPool
package com.boot.base.common.util.hdfs;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.AbandonedConfig;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
public class HdfsPool extends GenericObjectPool<Hdfs> {
public HdfsPool(PooledObjectFactory<Hdfs> factory) {
super(factory);
}
public HdfsPool(PooledObjectFactory<Hdfs> factory, GenericObjectPoolConfig<Hdfs> config) {
super(factory, config);
}
public HdfsPool(PooledObjectFactory<Hdfs> factory, GenericObjectPoolConfig<Hdfs> config, AbandonedConfig abandonedConfig) {
super(factory, config, abandonedConfig);
}
}
5.HdfsClient
package com.boot.base.common.util.hdfs;
import com.boot.base.common.exception.WorkException;
import com.boot.base.common.util.FileUtil;
import com.boot.base.common.util.LogUtil;
import com.boot.base.config.hdfs.HdfsPoolConfig;
import com.boot.dto.salesLeads.DeptSignForecastExportModel;
import org.apache.hadoop.fs.ContentSummary;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class HdfsClient {
private HdfsPool hdfsPool;
@Autowired
private HdfsPoolConfig hdfsPoolConfig;
@Autowired
private HdfsFactory hdfsFactory;
public void init() {
hdfsPool = new HdfsPool(hdfsFactory, hdfsPoolConfig);
}
public long getPathSize(String path) throws Exception {
Hdfs hdfs = null;
try {
hdfs = hdfsPool.borrowObject();
return hdfs.getContentSummary(path).getLength();
} catch (Exception e) {
LogUtil.error("[HDFS]获取路径大小失败", e);
throw e;
} finally {
if (null != hdfs) {
hdfsPool.returnObject(hdfs);
}
}
}
public List<String> getBasePath() {
Hdfs hdfs = null;
try {
hdfs = hdfsPool.borrowObject();
return hdfs.listFileName();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (null != hdfs) {
hdfsPool.returnObject(hdfs);
}
}
}
public List<String> getFileNameList(String path) {
Hdfs hdfs = null;
try {
hdfs = hdfsPool.borrowObject();
return hdfs.listFileName(path);
} catch (Exception e) {
LogUtil.error("获取hdfs指定目录下的所有文件名异常:", e);
return new ArrayList<>();
} finally {
if (null != hdfs) {
hdfsPool.returnObject(hdfs);
}
}
}
public boolean deleteFile(String path) throws WorkException {
Hdfs hdfs = null;
try {
hdfs = hdfsPool.borrowObject();
return hdfs.deleteFile(path);
} catch (Exception e) {
LogUtil.error("删除hdfs文件异常:", e);
throw new WorkException("删除文件异常!");
} finally {
if (null != hdfs) {
hdfsPool.returnObject(hdfs);
}
}
}
public String uploadFileByStream(InputStream in, String path) throws Exception {
Hdfs hdfs = null;
try {
hdfs = hdfsPool.borrowObject();
return hdfs.uploadFileByStream(in, path);
} finally {
if (null != hdfs) {
hdfsPool.returnObject(hdfs);
}
}
}
public void downloadFileByStream(String path) throws Exception {
Hdfs hdfs = null;
OutputStream os = null;
InputStream in = null;
try {
hdfs = hdfsPool.borrowObject();
in = hdfs.downloadFileByStream(path);
String fileName = new Path(path).getName();
int index;
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
response.setCharacterEncoding("UTF-8");
response.setContentType("application/octet-stream; charset=utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
os = response.getOutputStream();
byte[] buffer = new byte[in.available()];
while ((index = in.read(buffer)) != -1) {
os.write(buffer, 0, index);
os.flush();
}
} finally {
if (null != hdfs) {
hdfsPool.returnObject(hdfs);
}
if (os != null) {
os.close();
}
if (in != null) {
in.close();
}
}
}
public String downloadSingleFile(String filePath, HttpServletRequest request, HttpServletResponse response) throws Exception {
Hdfs hdfs = null;
InputStream in = null;
BufferedInputStream br = null;
OutputStream os = null;
try {
hdfs = hdfsPool.borrowObject();
if (!hdfs.exists(filePath)) {
throw new WorkException("hdfs上的文件:" + filePath + "不存在!");
}
Path hdfsPath = hdfs.getPath(filePath);
ContentSummary hdfsContentSummary = hdfs.getContentSummary(filePath);
in = new BufferedInputStream(hdfs.downloadFileByStream(filePath));
byte[] buffer = new byte[in.available()];
in.read(buffer);
String agent = request.getHeader("user-agent");
String fileName = hdfsPath.getName();
if (agent.contains("FireFox")) {
fileName = new String(fileName.getBytes("UTF-8"), "iso-8859-1");
} else {
fileName = URLEncoder.encode(fileName, "UTF-8");
}
response.reset();
response.setCharacterEncoding("UTF-8");
String mineType = request.getServletContext().getMimeType(fileName);
response.setContentType(mineType);
response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
response.addHeader("Content-Length", "" + hdfsContentSummary.getLength());
os = new BufferedOutputStream(response.getOutputStream());
os.write(buffer);
os.flush();
} finally {
if (null != hdfs) {
hdfsPool.returnObject(hdfs);
}
if (os != null) {
os.close();
}
if (br != null) {
br.close();
}
if (in != null) {
in.close();
}
}
return filePath;
}
public String downloadMultipleFile(String filePath, List<String> fileNameList, String zipFileName, HttpServletResponse response) throws Exception {
InputStream in = null;
Hdfs hdfs = hdfsPool.borrowObject();
if (!hdfs.exists(filePath)) {
LogUtil.getLogger().error("hdfs上的文件目录:" + filePath + "不存在!");
throw new WorkException("所下载文件在文件服务器中不存在,请检查文件是否被误删!");
}
response.setContentType("application/*");
response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode( zipFileName + ".zip", "utf-8"));
response.setCharacterEncoding("UTF-8");
OutputStream os = new BufferedOutputStream(response.getOutputStream());
ZipOutputStream zos = null;
ByteArrayOutputStream bos;
try {
zos = new ZipOutputStream(os);
FileStatus[] fsts = hdfs.listFileStatus(filePath);
for (FileStatus fileStatus : fsts) {
String fileName = fileStatus.getPath().getName();
if (fileStatus.isFile() && fileNameList.contains(fileName)) {
in = new BufferedInputStream(hdfs.downloadFileByStream(fileStatus.getPath()));
byte[] buffer = new byte[in.available()];
in.read(buffer);
zos.putNextEntry(new ZipEntry(fileName));
bos = new ByteArrayOutputStream();
bos.write(buffer);
bos.writeTo(zos);
zos.closeEntry();
}
}
} finally {
try {
if (null != hdfs) {
hdfsPool.returnObject(hdfs);
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (zos != null) {
zos.flush();
zos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return filePath;
}
public InputStream downloadSingleFileByStream(String filePath) throws Exception {
Hdfs hdfs = null;
try {
hdfs = hdfsPool.borrowObject();
if (!hdfs.exists(filePath)) {
LogUtil.getLogger().error("文件:" + filePath + "不存在!");
throw new WorkException("文件不存在!");
}
return hdfs.downloadFileByStream(filePath);
} finally {
if (null != hdfs) {
hdfsPool.returnObject(hdfs);
}
}
}
public void stop() {
hdfsPool.close();
}
}
配置:
hdfs.url=hdfs://10.10.101.40:8020
hdfs.userName=admin
hdfs.size=50
#池化hdfs配置:
#连接池中最大连接数,默认为8
hdfs.pool.maxTotal=15
#连接池中最大空闲的连接数,默认也为8
hdfs.pool.maxIdle=8
#连接池中最少空闲的连接数,默认为0
hdfs.pool.minIdle=0
#当连接池资源耗尽时,等待时间,超出则抛异常,默认为-1即永不超时
hdfs.pool.maxWaitMillis=1800000
#连接空闲的最小时间,达到此值后空闲连接将可能会被移除。默认为1000L*60L*30L
hdfs.pool.minEvictableIdleTimeMillis=60000
#空闲连接检测线程检测的周期,毫秒数。如果为负值,表示不运行检测线程。默认为-1
hdfs.pool.timeBetweenEvictionRunsMillis=300000
参考:
commons.pool2 对象池的使用
BaseObjectPoolConfig