Hongwei's Diary
Fork me on GitHub

阿里云OSS多个文件打包下载

2018-12-19

在阿里云OSS文件只有下载单个文件的教程,本文介绍多个OSS文件压缩打包成zip下载的步骤。

一、添加Aliyun Open Services SDK依赖

<openservices.version>1.2.3</openservices.version>

<dependency>
<groupId>com.aliyun.openservices</groupId>
<artifactId>aliyun-openservices</artifactId>
<version>${openservices.version}</version>
</dependency>

二、创建OSSClientUtil操作OSS

public class OSSClientUtil {

//log
private static final Logger logger = LoggerFactory.getLogger(OSSClientUtil.class);

//阿里云API的内或外网域名
private static final String ENDPOINT = "http://oss-cn-beijing.aliyuncs.com";
//阿里云API的密钥Access Key ID
private static final String ACCESS_KEY_ID = "xxxxxxxxx";
//阿里云API的密钥Access Key Secret
private static final String ACCESS_KEY_SECRET = "xxxxxxxxxxxx";
// 操作的 bucket
private static final String BUCKET_NAME = "xxx";
/**
* 获取阿里云OSS客户端对象
*/
public static final OSSClient OSSClient = new OSSClient(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);


/**
* 新建Bucket --Bucket权限:私有
*
* @param bucketName bucket名称
* @return true 新建Bucket成功
*/
public static final boolean createBucket(OSSClient client, String bucketName) {
Bucket bucket = client.createBucket(bucketName);
return bucketName.equals(bucket.getName());
}

// /**
// * 删除Bucket
// *
// * @param bucketName bucket名称
// */
// public static final void deleteBucket(OSSClient client, String bucketName) {
// client.deleteBucket(bucketName);
// logger.info("删除" + bucketName + "Bucket成功");
// }

/**
* 向阿里云的OSS存储中存储文件 --file也可以用InputStream替代
*
* @param client OSS客户端
* @param file 上传文件
* @param bucketName bucket名称
* @param diskName 上传文件的目录 --bucket下文件的路径
* @return String 唯一MD5数字签名
*/
public static final String uploadObject2OSS(OSSClient client, File file, String bucketName, String diskName) {
String resultStr = null;
try {
InputStream is = new FileInputStream(file);
String fileName = file.getName();
Long fileSize = file.length();
//创建上传Object的Metadata
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(is.available());
// metadata.setCacheControl("no-cache");
// metadata.setHeader("Pragma", "no-cache");
metadata.setContentEncoding("utf-8");
metadata.setContentType(getContentType(fileName));
// metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
//上传文件
PutObjectResult putResult = client.putObject(bucketName, diskName + fileName, is, metadata);
//解析结果
resultStr = putResult.getETag();
} catch (Exception e) {
e.printStackTrace();
}
return resultStr;
}

/**
* 根据key获取OSS服务器上的文件输入流
*
* @param client OSS客户端
* @param bucketName bucket名称
* @param diskName 文件路径
* @param key Bucket下的文件的路径名+文件名
*/
public static InputStream getOSS2InputStream(OSSClient client, String bucketName, String diskName, String key) {
OSSObject ossObj = client.getObject(bucketName, diskName + key);
return ossObj.getObjectContent();
}

public static InputStream getObjectInputStream(String key) {
OSSObject ossObj = OSSClient.getObject(BUCKET_NAME, key);
return ossObj.getObjectContent();
}

/**
* 根据key删除OSS服务器上的文件
*
* @param diskName Bucket下的文件的路径名+文件名
*/
public static void deleteFile(String diskName) {
OSSClient.deleteObject(BUCKET_NAME, diskName);
logger.info("删除" + BUCKET_NAME + "下的文件" + diskName + "成功");
}

/**
* 通过文件名判断并获取OSS服务文件上传时文件的contentType
*
* @param fileName 文件名
* @return 文件的contentType
*/
public static final String getContentType(String fileName) {
String fileExtension = fileName.substring(fileName.lastIndexOf(".") + 1);
if ("png".equalsIgnoreCase(fileExtension)) {
return "image/png";
}
if ("bmp".equalsIgnoreCase(fileExtension)) {
return "image/bmp";
}
if ("gif".equalsIgnoreCase(fileExtension)) {
return "image/gif";
}
if ("jpeg".equalsIgnoreCase(fileExtension) || "jpg".equalsIgnoreCase(fileExtension)) {
return "image/jpeg";
}
if ("html".equalsIgnoreCase(fileExtension)) {
return "text/html";
}
if ("txt".equalsIgnoreCase(fileExtension)) {
return "text/plain";
}
if ("vsd".equalsIgnoreCase(fileExtension)) {
return "application/vnd.visio";
}
if ("ppt".equalsIgnoreCase(fileExtension) || "pptx".equalsIgnoreCase(fileExtension)) {
return "application/vnd.ms-powerpoint";
}
if ("doc".equalsIgnoreCase(fileExtension) || "docx".equalsIgnoreCase(fileExtension)) {
return "application/msword";
}
if ("xml".equalsIgnoreCase(fileExtension)) {
return "text/xml";
}
if ("zip".equalsIgnoreCase(fileExtension)) {
return "application/zip";
}
return "text/html";
}


/**
* 上传文件到阿里云oss
*
* @param filePath 文件路径
* @param diskName oss上文件的路径
* @return 上传文件名
*/
public static String scpFileToOss(String filePath, String diskName) {
//上传文件
File file = new File(filePath);
String md5key = uploadObject2OSS(OSSClient, file, BUCKET_NAME, diskName);
logger.info("上传cdn成功,MD5数字唯一签名:" + md5key); //上传后的文件MD5数字唯一签名:A30B046A34EB326C4A3BBD784333B017
String[] split = filePath.split("/");
return split[split.length - 1];
}

public static String scpFileToOss(File file, String diskName) {
//上传文件
String md5key = uploadObject2OSS(OSSClient, file, BUCKET_NAME, diskName);
logger.info("上传cdn成功,MD5数字唯一签名:" + md5key); //上传后的文件MD5数字唯一签名:A30B046A34EB326C4A3BBD784333B017
return md5key;
}


/**
* 上传整个文件夹的文件到阿里云oss
*
* @param folderPath 文件夹路径
* @param diskName oss上文件的路径
* @return 上传结果唯一MD5数字签名
*/
public static void scpFolderToOss(String folderPath, String diskName) {
File dirFile = new File(folderPath);
if (!dirFile.exists()) {
System.out.println("文件夹不存在");
return;
}
if (!dirFile.isDirectory()) {
System.out.println("不是一个文件夹路径");
return;
}
File[] fileList = dirFile.listFiles();
Arrays.stream(fileList).forEach(file -> scpFileToOss(file.getPath(), diskName));
}

/**
* 删除 OSS上的文件夹下所有文件
* 需要先列出该文件下的所有对象
*
* @param diskName 文件夹路径
*/
public static void deleteFolder(String diskName) {
// 列举Object。 如KeyPrifex参数为空,则列举Bucket下所有的Object。如KeyPrifex参数不为空,则列举包含指定前缀的Object。
// 构造ListObjectsRequest请求。
ListObjectsRequest listObjectsRequest = new ListObjectsRequest(BUCKET_NAME);
//设置 Prefix 参数来获取某个目录(fun/)下的所有文件
System.out.println(diskName);
listObjectsRequest.setPrefix(diskName);
// 递归列出fun目录下的所有文件。
ObjectListing listing = OSSClient.listObjects(listObjectsRequest);
// 遍历所有Object。
System.out.println("Objects:");
for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
System.out.println(objectSummary.getKey());
deleteFile(objectSummary.getKey());
}
}


}

三、打包批量下载

SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd_HHmmss");
String prefixName = "XXXXXX_SDK_" + format.format(new Date());
String fileName = prefixName + ".zip";
// 创建临时文件
File zipFile = File.createTempFile(prefixName, ".zip");
FileOutputStream outputStream = new FileOutputStream(zipFile);
/**
* 作用是为任何OutputStream产生校验和
* 第一个参数是制定产生校验和的输出流,第二个参数是指定Checksum的类型 (Adler32(较快)和CRC32两种)
*/
CheckedOutputStream csum = new CheckedOutputStream(outputStream, new Adler32());
// 用于将数据压缩成Zip文件格式
ZipOutputStream zos = new ZipOutputStream(csum);
// 遍历所有的需要下载的oss文件
for (SdkPackage sdkPackage : sdkPackages) {
InputStream inputStream = null;
try {
// 获取输入流
inputStream = OSSClientUtil.getObjectInputStream(sdkPackage.getSdkURL());
} catch (Exception e) {
// 文件不存在 或者 读取失败 跳过
continue;
}
// zip 中新建 entry实例 传入文件名
zos.putNextEntry(new ZipEntry(sdkPackage.getSdkName()));
int readCount = -1;
byte[] bytes = new byte[1024];
// 向压缩文件中输出数据
while ((readCount = inputStream.read(bytes)) != -1) {
zos.write(bytes, 0, readCount);
}

inputStream.close();
zos.closeEntry(); // 当前文件写完,定位为写入下一条项目
}
zos.close();
String header = request.getHeader("User-Agent").toUpperCase();
if (header.contains("MSIE") || header.contains("TRIDENT") || header.contains("EDGE")) {
fileName = URLEncoder.encode(fileName, "utf-8");
fileName = fileName.replace("+", "%20"); //IE下载文件名空格变+号问题
} else {
fileName = new String(fileName.getBytes(), "ISO8859-1");
}
response.reset();
response.setContentType("text/plain");
response.setContentType("application/octet-stream; charset=utf-8");
response.setHeader("Location", fileName);
response.setHeader("Cache-Control", "max-age=0");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);

FileInputStream fis = new FileInputStream(zipFile);
BufferedInputStream buff = new BufferedInputStream(fis);
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
byte[] car = new byte[1024];
int l = 0;
while (l < zipFile.length()) {
int j = buff.read(car, 0, 1024);
l += j;
out.write(car, 0, j);
}
// 关闭流
fis.close();
buff.close();
out.close();

// 删除临时文件
zipFile.delete();
使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章