From f53054b4985df6a282e960a253f5b7f5a627137a Mon Sep 17 00:00:00 2001 From: cxb <946074639@qq.com> Date: Wed, 5 Nov 2025 17:32:34 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E4=BC=98=E5=8C=96=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E6=96=87=E4=BB=B6=E7=9B=AE=E5=BD=95=E5=8F=8A=E6=97=97?= =?UTF-8?q?=E4=B8=8B=E6=96=87=E4=BB=B6=E5=A4=A7=E5=B0=8F=E4=BB=A5=E5=8F=8A?= =?UTF-8?q?=E5=8D=95=E6=96=87=E4=BB=B6=E5=A4=A7=E5=B0=8F=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../huaweicloudOBS/HuaweicloudOBSStorage.java | 469 +++++++++--------- 1 file changed, 242 insertions(+), 227 deletions(-) diff --git a/src/main/java/cn/zvo/fileupload/storage/huaweicloudOBS/HuaweicloudOBSStorage.java b/src/main/java/cn/zvo/fileupload/storage/huaweicloudOBS/HuaweicloudOBSStorage.java index 5bc3dbc..5fae3fe 100644 --- a/src/main/java/cn/zvo/fileupload/storage/huaweicloudOBS/HuaweicloudOBSStorage.java +++ b/src/main/java/cn/zvo/fileupload/storage/huaweicloudOBS/HuaweicloudOBSStorage.java @@ -1,227 +1,242 @@ -package cn.zvo.fileupload.storage.huaweicloudOBS; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import com.obs.services.model.DeleteObjectResult; -import com.obs.services.model.ListObjectsRequest; -import com.obs.services.model.ObjectListing; -import com.obs.services.model.ObsObject; -import com.obs.services.model.PutObjectResult; -import com.xnx3.BaseVO; -import cn.zvo.fileupload.StorageInterface; -import cn.zvo.fileupload.bean.SubFileBean; -import cn.zvo.fileupload.vo.StorageConfigVO; -import cn.zvo.fileupload.vo.UploadFileVO; -import cn.zvo.fileupload.vo.bean.Param; - -/** - * 文件上传之 华为云 OBS - * @author 管雷鸣 - * - */ -public class HuaweicloudOBSStorage implements StorageInterface { - public OBSHandler obsHandler; //禁用,通过getObsUtil() 获取 - public String obsBucketName; // 当前进行操作桶的名称 - - /** - * 文件上传-华为云OBS - * @param accessKeyId 华为云的 Access Key Id - * @param accessKeySecret 华为云的 Access Key Secret - * @param endpoint 区域,传入格式如 "obs.cn-north-4.myhuaweicloud.com" ,详细可参考 https://developer.huaweicloud.com/endpoint?OBS - * @param obsname 桶的名称 - */ - public HuaweicloudOBSStorage(String accessKeyId, String accessKeySecret, String endpoint, String obsname) { - obsHandler = new OBSHandler(accessKeyId,accessKeySecret,endpoint); - // 如果设置过CDN的路径测设置为CDN路径,没有设置则为桶原生的访问路径 -// obsHandler.setUrlForCDN(netUrl); - // 在数据库中读取进行操作的桶的明恒 - obsHandler.setObsBucketName(obsname); - // 对桶名称进行当前类内缓存 - obsBucketName = obsHandler.getObsBucketName(); - } - - - /** - * 文件上传-华为云OBS - * @param map 传入一个 Map 其中map要定义这么几个参数: - * - */ - public HuaweicloudOBSStorage(Map map) { - String accessKeySecret = map.get("accessKeySecret"); - String accessKeyId = map.get("accessKeyId"); - String endpoint = map.get("endpoint"); - String obsname = map.get("obsname"); - - init(accessKeyId, accessKeySecret, endpoint, obsname); - } - - /** - * 初始化这个类,以供构造方法调用 - * @param accessKeyId 华为云的 Access Key Id - * @param accessKeySecret 华为云的 Access Key Secret - * @param endpoint 区域,传入格式如 "obs.cn-north-4.myhuaweicloud.com" ,详细可参考 https://developer.huaweicloud.com/endpoint?OBS - * @param obsname 桶的名称 - */ - private void init(String accessKeyId, String accessKeySecret, String endpoint, String obsname) { - obsHandler = new OBSHandler(accessKeyId,accessKeySecret,endpoint); - // 如果设置过CDN的路径测设置为CDN路径,没有设置则为桶原生的访问路径 -// obsHandler.setUrlForCDN(netUrl); - // 在数据库中读取进行操作的桶的明恒 - obsHandler.setObsBucketName(obsname); - // 对桶名称进行当前类内缓存 - obsBucketName = obsHandler.getObsBucketName(); - } - - - /** - * 获取华为云OBS的操作类 - * @return 当前华为云OBS的操作类型 - */ - public OBSHandler getObsHander() { - return obsHandler; - } - - /** - * 通过流进行上传文件 - * @param path 上传文件路径和名称 例:"site/1.txt" - * @param inputStream 需要上传文件的输入流 - * @return {@link com.xnx3.j2ee.vo.UploadFileVO} result 1: 成功;0 失败。 - */ - @Override - public UploadFileVO upload(String path, InputStream inputStream) { - UploadFileVO vo = getObsHander().putFileByStream(obsBucketName, path, inputStream); - return vo; - } - - /** - * 删除文件 - * @param path 需要删除的文件路径加名称 例:"site/219/index.html" - * @return {@link BaseVO} - */ - @Override - public BaseVO delete(String path) { - DeleteObjectResult result = getObsHander().deleteObject(obsBucketName, path); - - //成功 - if(result.getStatusCode() == 200) { - return BaseVO.success(); - }else { - return BaseVO.failure("failure, code:"+result.getStatusCode()+", obs requestId:"+result.getRequestId()); - } - } - - /** - * OBS内对象复制 - * @param originalFilePath 源文件的路径和文件名 例:"site/2010/example.txt" - * @param newFilePath 目标文件的路径和文件名 例:"site/2010/example_bak.txt" - */ - @Override - public void copyFile(String originalFilePath, String newFilePath) { - getObsHander().copyObject(obsBucketName, originalFilePath, obsBucketName, newFilePath); - } - - @Override - public List getSubFileList(String path) { - List list = new ArrayList(); - if(path == null || path.length() == 0){ - return list; - } - - ListObjectsRequest request = new ListObjectsRequest(obsBucketName); - request.setPrefix(path); - request.setMaxKeys(100); - ObjectListing result; - do{ - result = getObsHander().getObsClient().listObjects(request); - for(ObsObject obsObject : result.getObjects()){ - SubFileBean bean = new SubFileBean(); - bean.setPath(obsObject.getObjectKey()); - bean.setSize(obsObject.getMetadata().getContentLength()); - bean.setLastModified(obsObject.getMetadata().getLastModified().getTime()); -// obsObject.getMetadata(). - //判断是否是目录。SDK没有直接判断是否是目录的方法,采用这种方式。 - if(path != null && bean.getSize() < 1) { - if(bean.getPath().lastIndexOf("/") == bean.getPath().length()-1) { - bean.setFolder(true); - } - } - list.add(bean); - } - request.setMarker(result.getNextMarker()); - }while(result.isTruncated()); - - return list; - } - - @Override - public long getSize(String path) { - if(path == null) { - return -1; - } - - if((path.lastIndexOf("/") +1 ) == path.length()) { - //是目录 - return getObsHander().getFolderObjectsSize(obsBucketName, path); - }else { - //是文件 - com.obs.services.model.ObjectMetadata metadata = getObsHander().getObsClient().getObjectMetadata(obsBucketName, path); - if(metadata == null){ - return -1; - } - - return metadata.getContentLength(); - } - } - - @Override - public BaseVO createFolder(String path) { - PutObjectResult result = getObsHander().mkdirFolder(obsBucketName, path); - UploadFileVO uploadFileVO = getObsHander().getUploadFileVO(result); - - BaseVO vo = new BaseVO(); - vo.setBaseVO(uploadFileVO.getResult(), uploadFileVO.getInfo()); - return vo; - } - - @Override - public InputStream get(String path) { - String content = null; - byte[] bytes = null; - try { - bytes = getObsHander().getFileByteArray(obsBucketName, path); - } catch (IOException e) { - e.printStackTrace(); - } - if(bytes == null){ - return null; - } - - InputStream input = new ByteArrayInputStream(bytes); - return input; - } - - - @Override - public StorageConfigVO config() { - StorageConfigVO vo = new StorageConfigVO(); - vo.setName("华为云OBS"); - vo.setDescription("华为云对象存储OBS"); - vo.getParamList().add(new Param("accessKeyId", "Access Key Id", "华为云的 Access Key Id", true, "")); - vo.getParamList().add(new Param("accessKeySecret", "Access Key Secret", "华为云的 Access Key Secret", true, "")); - vo.getParamList().add(new Param("endpoint", "endpoint", "传入格式如 \"obs.cn-north-4.myhuaweicloud.com\" ,详细可参考 https://developer.huaweicloud.com/endpoint?OBS", true, "")); - vo.getParamList().add(new Param("obsname", "桶名称", "所建立的OBS存储桶的名字,需要提前创建好", true, "")); - - return vo; - } - -} +package cn.zvo.fileupload.storage.huaweicloudOBS; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import com.obs.services.model.DeleteObjectResult; +import com.obs.services.model.ListObjectsRequest; +import com.obs.services.model.ObjectListing; +import com.obs.services.model.ObsObject; +import com.obs.services.model.PutObjectResult; +import com.xnx3.BaseVO; +import cn.zvo.fileupload.StorageInterface; +import cn.zvo.fileupload.bean.SubFileBean; +import cn.zvo.fileupload.vo.StorageConfigVO; +import cn.zvo.fileupload.vo.UploadFileVO; +import cn.zvo.fileupload.vo.bean.Param; + +/** + * 文件上传之 华为云 OBS + * @author 管雷鸣 + * + */ +public class HuaweicloudOBSStorage implements StorageInterface { + public OBSHandler obsHandler; //禁用,通过getObsUtil() 获取 + public String obsBucketName; // 当前进行操作桶的名称 + + /** + * 文件上传-华为云OBS + * @param accessKeyId 华为云的 Access Key Id + * @param accessKeySecret 华为云的 Access Key Secret + * @param endpoint 区域,传入格式如 "obs.cn-north-4.myhuaweicloud.com" ,详细可参考 https://developer.huaweicloud.com/endpoint?OBS + * @param obsname 桶的名称 + */ + public HuaweicloudOBSStorage(String accessKeyId, String accessKeySecret, String endpoint, String obsname) { + obsHandler = new OBSHandler(accessKeyId,accessKeySecret,endpoint); + // 如果设置过CDN的路径测设置为CDN路径,没有设置则为桶原生的访问路径 +// obsHandler.setUrlForCDN(netUrl); + // 在数据库中读取进行操作的桶的明恒 + obsHandler.setObsBucketName(obsname); + // 对桶名称进行当前类内缓存 + obsBucketName = obsHandler.getObsBucketName(); + } + + + /** + * 文件上传-华为云OBS + * @param map 传入一个 Map 其中map要定义这么几个参数: + *
    + *
  • map.put("accessKeyId", "华为云的 Access Key Id");
  • + *
  • map.put("accessKeySecret", "华为云的 Access Key Secret");
  • + *
  • map.put("endpoint", "区域,传入格式如 obs.cn-north-4.myhuaweicloud.com"); //详细可参考 https://developer.huaweicloud.com/endpoint?OBS
  • + *
  • map.put("obsname", "桶的名称")
  • + *
+ */ + public HuaweicloudOBSStorage(Map map) { + String accessKeySecret = map.get("accessKeySecret"); + String accessKeyId = map.get("accessKeyId"); + String endpoint = map.get("endpoint"); + String obsname = map.get("obsname"); + + init(accessKeyId, accessKeySecret, endpoint, obsname); + } + + /** + * 初始化这个类,以供构造方法调用 + * @param accessKeyId 华为云的 Access Key Id + * @param accessKeySecret 华为云的 Access Key Secret + * @param endpoint 区域,传入格式如 "obs.cn-north-4.myhuaweicloud.com" ,详细可参考 https://developer.huaweicloud.com/endpoint?OBS + * @param obsname 桶的名称 + */ + private void init(String accessKeyId, String accessKeySecret, String endpoint, String obsname) { + obsHandler = new OBSHandler(accessKeyId,accessKeySecret,endpoint); + // 如果设置过CDN的路径测设置为CDN路径,没有设置则为桶原生的访问路径 +// obsHandler.setUrlForCDN(netUrl); + // 在数据库中读取进行操作的桶的明恒 + obsHandler.setObsBucketName(obsname); + // 对桶名称进行当前类内缓存 + obsBucketName = obsHandler.getObsBucketName(); + } + + + /** + * 获取华为云OBS的操作类 + * @return 当前华为云OBS的操作类型 + */ + public OBSHandler getObsHander() { + return obsHandler; + } + + /** + * 通过流进行上传文件 + * @param path 上传文件路径和名称 例:"site/1.txt" + * @param inputStream 需要上传文件的输入流 + * @return {@link com.xnx3.j2ee.vo.UploadFileVO} result 1: 成功;0 失败。 + */ + @Override + public UploadFileVO upload(String path, InputStream inputStream) { + UploadFileVO vo = getObsHander().putFileByStream(obsBucketName, path, inputStream); + return vo; + } + + /** + * 删除文件 + * @param path 需要删除的文件路径加名称 例:"site/219/index.html" + * @return {@link BaseVO} + */ + @Override + public BaseVO delete(String path) { + DeleteObjectResult result = getObsHander().deleteObject(obsBucketName, path); + + //成功 + if(result.getStatusCode() == 200) { + return BaseVO.success(); + }else { + return BaseVO.failure("failure, code:"+result.getStatusCode()+", obs requestId:"+result.getRequestId()); + } + } + + /** + * OBS内对象复制 + * @param originalFilePath 源文件的路径和文件名 例:"site/2010/example.txt" + * @param newFilePath 目标文件的路径和文件名 例:"site/2010/example_bak.txt" + */ + @Override + public void copyFile(String originalFilePath, String newFilePath) { + getObsHander().copyObject(obsBucketName, originalFilePath, obsBucketName, newFilePath); + } + + @Override + public List getSubFileList(String path) { + List list = new ArrayList(); + if(path == null || path.length() == 0){ + return list; + } + + ListObjectsRequest request = new ListObjectsRequest(obsBucketName); + request.setPrefix(path); + request.setMaxKeys(100); + ObjectListing result; + do{ + result = getObsHander().getObsClient().listObjects(request); + for(ObsObject obsObject : result.getObjects()){ + SubFileBean bean = new SubFileBean(); + bean.setPath(obsObject.getObjectKey()); + bean.setSize(obsObject.getMetadata().getContentLength()); + bean.setLastModified(obsObject.getMetadata().getLastModified().getTime()); +// obsObject.getMetadata(). + //判断是否是目录。SDK没有直接判断是否是目录的方法,采用这种方式。 + if(path != null && bean.getSize() < 1) { + if(bean.getPath().lastIndexOf("/") == bean.getPath().length()-1) { + bean.setFolder(true); + } + } + list.add(bean); + } + request.setMarker(result.getNextMarker()); + }while(result.isTruncated()); + + return list; + } + + @Override + public long getSize(String path) { + if(path == null) { + return -1; + } + + if((path.lastIndexOf("/") + 1) == path.length()) { + // 目录:统计该前缀下所有对象占用的总字节数;不存在则返回 -1 + java.util.List objects = getObsHander().getFolderObjects(obsBucketName, path); + if(objects == null || objects.isEmpty()) { + return -1; + } + long total = 0L; + for(com.obs.services.model.ObsObject obj : objects) { + com.obs.services.model.ObjectMetadata md = obj.getMetadata(); + if(md != null) { + total += md.getContentLength(); + } + } + return total; + }else { + // 文件:返回对象的 Content-Length;不存在或异常返回 -1 + com.obs.services.model.ObjectMetadata metadata = null; + try { + metadata = getObsHander().getObsClient().getObjectMetadata(obsBucketName, path); + } catch (Exception e) { + metadata = null; + } + if(metadata == null){ + return -1; + } + return metadata.getContentLength(); + } + } + + @Override + public BaseVO createFolder(String path) { + PutObjectResult result = getObsHander().mkdirFolder(obsBucketName, path); + UploadFileVO uploadFileVO = getObsHander().getUploadFileVO(result); + + BaseVO vo = new BaseVO(); + vo.setBaseVO(uploadFileVO.getResult(), uploadFileVO.getInfo()); + return vo; + } + + @Override + public InputStream get(String path) { + String content = null; + byte[] bytes = null; + try { + bytes = getObsHander().getFileByteArray(obsBucketName, path); + } catch (IOException e) { + e.printStackTrace(); + } + if(bytes == null){ + return null; + } + + InputStream input = new ByteArrayInputStream(bytes); + return input; + } + + + @Override + public StorageConfigVO config() { + StorageConfigVO vo = new StorageConfigVO(); + vo.setName("华为云OBS"); + vo.setDescription("华为云对象存储OBS"); + vo.getParamList().add(new Param("accessKeyId", "Access Key Id", "华为云的 Access Key Id", true, "")); + vo.getParamList().add(new Param("accessKeySecret", "Access Key Secret", "华为云的 Access Key Secret", true, "")); + vo.getParamList().add(new Param("endpoint", "endpoint", "传入格式如 \"obs.cn-north-4.myhuaweicloud.com\" ,详细可参考 https://developer.huaweicloud.com/endpoint?OBS", true, "")); + vo.getParamList().add(new Param("obsname", "桶名称", "所建立的OBS存储桶的名字,需要提前创建好", true, "")); + + return vo; + } + +} -- Gitee