开发者社区 > 云存储 > 对象存储OSS > 正文

oss正确关闭流,及连接池方式样例

如何正确使用oss服务开发后端存储附件,java项目哦

展开
收起
ap8452o3d 2023-05-15 15:38:00 841 0
5 条回答
写回答
取消 提交回答
  • 可将OSS服务中对应流转成Java对象,流对象读取到字节数组中(如果文件较大可以读到本地临时文件) 然后,可以直接释放连接。 敬请期待高手实现代码

    2023-05-24 15:38:05
    赞同 展开评论 打赏
  • 公众号:网络技术联盟站,InfoQ签约作者,阿里云社区签约作者,华为云 云享专家,BOSS直聘 创作王者,腾讯课堂创作领航员,博客+论坛:https://www.wljslmz.cn,工程师导航:https://www.wljslmz.com

    使用阿里云 OSS 服务开发后端存储附件,大致可以分为以下步骤:

    1. 创建 OSS 客户端

    在 Java 项目中使用阿里云 OSS 服务,需要先引入 OSS 客户端 SDK,并在代码中创建 OSS 客户端。创建 OSS 客户端代码示例:

    import com.aliyun.oss.OSS;
    import com.aliyun.oss.OSSClientBuilder;
    
    public class OSSUtils {
        private static final String endpoint = "<oss_endpoint>";
        private static final String accessKeyId = "<accessKeyId>";
        private static final String accessKeySecret = "<accessKeySecret>";
    
        public static OSS getOSSClient() {
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            return ossClient;
        }
    }
    

    在代码中,需要将与阿里云 OSS 相关的参数替换为自己的信息,例如 endpoint、accessKeyId、accessKeySecret 等。

    1. 上传附件到 OSS

    创建 OSS 客户端后,就可以在 Java 代码中使用 OSS 客户端上传附件。上传代码示例:

    import java.io.*;
    
    import com.aliyun.oss.OSS;
    import com.aliyun.oss.model.ObjectMetadata;
    import com.aliyun.oss.model.PutObjectRequest;
    import com.aliyun.oss.model.PutObjectResult;
    
    public class FileUploadUtils {
        private static String bucketName = "<bucketName>";
        private static String objectName = "<objectName>";
    
        public static void upload(File file) throws FileNotFoundException {
            if (!file.exists()) {
                throw new FileNotFoundException("文件不存在");
            }
            // 创建 OSS 客户端
            OSS ossClient = OSSUtils.getOSSClient();
            InputStream in = new FileInputStream(file);
            long contentLength = file.length();
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(contentLength);
    
            PutObjectRequest request = new PutObjectRequest(bucketName, objectName, in, metadata);
            PutObjectResult result = ossClient.putObject(request);
            System.out.println("Object:" + result.getKey() + "存储在OSS上");
            // 关闭 OSS 客户端
            ossClient.shutdown();
        }
    }
    

    在代码中,需要将上传的 bucketName、objectName 等参数替换为自己的信息。上传附件的方法是将要上传的文件转换成 InputStream,然后通过 OSS 客户端的 putObject 请求上传至阿里云 OSS 服务。

    1. 下载附件

    将附件上传到 OSS 后,就可以使用 OSS 客户端下载附件。下载代码示例:

    import java.io.*;
    
    import com.aliyun.oss.OSS;
    import com.aliyun.oss.model.OSSObject;
    
    public class FileDownloadUtils {
        private static String bucketName = "<bucketName>";
        private static String objectName = "<objectName>";
    
        public static void download(String localFilePath) throws IOException {
            // 创建 OSS 客户端
            OSS ossClient = OSSUtils.getOSSClient();
            OSSObject ossObject = ossClient.getObject(bucketName, objectName);
            InputStream inputStream = ossObject.getObjectContent();
            File file = new File(localFilePath);
            FileOutputStream out = new FileOutputStream(file);
            int ch;
            while ((ch = inputStream.read()) != -1) {
                out.write(ch);
            }
            inputStream.close();
            out.close();
            // 关闭 OSS 客户端
            ossClient.shutdown();
        }
    }
    

    在代码中,需要将下载的 bucketName、objectName 等参数替换为自己的信息。下载附件的方法是通过 OSS 客户端的 getObject 请求获取文件流,然后将文件流写入到本地文件中。

    以上是使用阿里云 OSS 服务开发后端存储附件的大致流程,在代码中需要根据需求进行详细的调整和优化。

    2023-05-23 12:00:50
    赞同 展开评论 打赏
  • 月移花影,暗香浮动

    使用阿里云OSS服务开发后端存储附件的一般步骤如下:

    1.注册阿里云账号,并开通OSS服务。

    2.创建一个OSS存储空间(Bucket)。

    3.配置Bucket的读写权限,一般建议将读写权限设置为私有。

    4.在代码中引入OSS SDK库,并按照SDK的文档进行初始化和鉴权操作。

    5.将附件文件上传至OSS存储空间中,并生成唯一的文件名作为文件的标识符。

    6.将文件标识符保存至数据库或其他数据存储中,以方便后续的处理和回溯。

    7.为了保证数据的安全性,可以考虑启用OSS的访问控制功能,对Bucket中的文件进行加密或压缩等保护操作。

    8.在需要访问存储附件的页面中,通过唯一的文件标识符可以获取到对应的文件URL,进而实现文件下载和预览等操作。

    需要注意的是,使用OSS存储附件一般需要配合其他服务实现,例如CDN加速、防盗链策略等,以满足不同业务场景下的需求。同时,在使用OSS服务开发的过程中,也需要关注流量和存储的收费标准,以尽可能降低成本。

    2023-05-15 17:08:37
    赞同 展开评论 打赏
  • 当操作完OSS的流后,需要关闭对应的流,否则会造成资源泄漏或者占用服务资源过多。关闭流的方式如下:

    if (inputStream != null) {
        try {
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    if (outputStream != null) {
        try {
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    关于OSS连接池的使用,推荐使用Alibaba Cloud SDK for Java中提供 OSSClientBuilder 来构建连接池的连接。在使用OSS服务时,我们一般都需要创建 OSSClient 实例,而 OSSClient 并不是线程安全的,所以需要使用连接池来减少每个线程创建的 OSSClient 实例和连接数。 示例代码如下:

    import com.aliyun.oss.OSSClient;
    import com.aliyun.oss.OSSClientBuilder;
    import com.aliyun.oss.common.auth.DefaultCredentialProvider;
    import com.aliyun.oss.common.comm.Protocol;
    import com.aliyun.oss.common.utils.AuthUtils;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.TimeUnit;
    
    public class OSSClientPool {
        // 连接池最大连接数
        private static int DEFAULT_MAX_CONNECTIONS = 100;
        // 默认的空闲时间(单位:毫秒)
        private static long DEFAULT_IDLE_TIMEOUT = 5 * 60 * 1000;
        // OSS连接池
        private BlockingQueue<OSSClient> ossClientPool = new ArrayBlockingQueue<OSSClient>(DEFAULT_MAX_CONNECTIONS);
        // OSS连接池中最多使用的连接数
        private int maxConnections;
        // OSS连接池中空闲连接的超时时间
        private long idleTimeout;
    
        // 构造函数
        public OSSClientPool() {
            this(DEFAULT_MAX_CONNECTIONS, DEFAULT_IDLE_TIMEOUT);
        }
    
        public OSSClientPool(int maxConnections, long idleTimeout) {
            this.maxConnections = maxConnections;
            this.idleTimeout = idleTimeout;
            initialize();
        }
    
        // 初始化OSS连接池
        private void initialize() {
            for (int i = 0; i < maxConnections; i++) {
                OSSClient ossClient = buildOSSClient();
                if (ossClient != null) {
                    ossClientPool.add(ossClient);
                }
            }
        }
    
        // 构建OSSClient实例
        private OSSClient buildOSSClient() {
            String endpoint = "yourEndPoint"; // 替换成自己的endpoint
            String accessKeyId = "yourAccessKeyId"; // 替换成自己的accessKeyId
            String accessKeySecret = "yourAccessKeySecret"; // 替换成自己的accessKeySecret
            boolean isCname = false; // 非CNAME模式
    
            OSSClient ossClient = null;
            try {
                ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
                ossClient.setEndpoint(endpoint);
                ossClient.setCredentials(new DefaultCredentialProvider(accessKeyId, accessKeySecret, null));
                ossClient.setProtocol(Protocol.HTTPS);
                ossClient.setTimeout(30000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return ossClient;
        }
    
        // 获取OSSClient连接
        public OSSClient getOSSClient() {
            OSSClient ossClient = null;
            try {
                ossClient = ossClientPool.poll(idleTimeout, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (ossClient == null) {
                ossClient = buildOSSClient();
            }
            return ossClient;
        }
    
        // 释放OSSClient连接
        public boolean releaseOSSClient(OSSClient ossClient) {
            return (ossClientPool.add(ossClient) || ossClientPool.offer(ossClient));
        }
    
        // 销毁OSS连接池
        public void destroy() {
            List<OSSClient> list = new ArrayList<OSSClient>();
            ossClientPool.drainTo(list);
            for (OSSClient ossClient : list) {
                ossClient.shutdown();
            }
        }
    }
    

    通过上述的方式,我们可以方便地使用OSS服务进行后端的存储附件。

    2023-05-15 16:07:46
    赞同 展开评论 打赏
  • 热爱开发

    在使用OSS服务时,正确关闭流是非常重要的,否则可能会导致资源泄露和其他问题。以下是一些建议:

    使用try-with-resources代码块来处理文件流,以确保在使用之后及时关闭流。例如: try (InputStream inputStream = new FileInputStream("local-file.txt"); OutputStream outputStream = new ossObject.getObjectContent()) { // 读取或写入文件内容 } catch (IOException e) { // 处理异常 } 如果您使用了第三方库来访问OSS服务,可以查看其文档以了解如何正确关闭流。

    如果您使用了连接池来管理OSS客户端对象,请确保在使用完毕后及时释放客户端对象,以减少资源占用。以下是Java OSS SDK连接池的一个示例:

    import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.comm.Protocol;

    import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.TimeUnit;

    public class OSSClientPool {

    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private Protocol protocol;
    private int maxIdleConnections;
    private long keepAliveTime;
    private BlockingQueue<OSS> pool;
    
    public OSSClientPool(String endpoint, String accessKeyId, String accessKeySecret, Protocol protocol, int maxIdleConnections, long keepAliveTime) {
        this.endpoint = endpoint;
        this.accessKeyId = accessKeyId;
        this.accessKeySecret = accessKeySecret;
        this.protocol = protocol;
        this.maxIdleConnections = maxIdleConnections;
        this.keepAliveTime = keepAliveTime;
        this.pool = new LinkedBlockingDeque<>(maxIdleConnections);
    }
    
    public OSS getClient() {
        OSS client = pool.poll();
        if (client == null) {
            client = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, protocol);
        }
        return client;
    }
    
    public void releaseClient(OSS client) {
        if (client != null && pool.size() < maxIdleConnections) {
            pool.offer(client);
        } else {
            client.shutdown();
        }
    }
    
    public void close() {
        for (OSS client : pool) {
            client.shutdown();
        }
        pool.clear();
    }
    
    public static void main(String[] args) throws Exception {
        String endpoint = "<yourEndpoint>";
        String accessKeyId = "<yourAccessKeyId>";
        String accessKeySecret = "<yourAccessKeySecret>";
    
        // 创建连接池
        OSSClientPool pool = new OSSClientPool(endpoint, accessKeyId, accessKeySecret, Protocol.HTTPS, 10, TimeUnit.MINUTES.toMillis(5));
    
        try (OSS client = pool.getClient()) {
            // 使用客户端对象进行操作
            client.putObject("<yourBucketName>", "<yourObjectName>", "<yourContent>");
        }
    
        // 关闭连接池
        pool.close();
    }
    

    } 注意:需要根据实际情况调整连接池的配置参数,例如最大空闲连接数和保持连接时间等。同时,如果您的应用程序需要频繁访问OSS服务,建议使用连接池来提高性能和减少资源消耗。

    2023-05-15 15:52:26
    赞同 2 展开评论 打赏
问答标签:
相关产品:

相关产品

  • 对象存储
  • 相关电子书

    更多
    OSS运维进阶实战手册 立即下载
    《OSS运维基础实战手册》 立即下载
    OSS运维基础实战手册 立即下载