oss正确关闭流,及连接池方式样例[阿里云oss]

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

「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
=====这是一个广告位,招租中,联系qq 78315851====
4 条回复 A 作者 M 管理员
  1. 可将OSS服务中对应流转成Java对象,流对象读取到字节数组中(如果文件较大可以读到本地临时文件) 然后,可以直接释放连接。 敬请期待高手实现代码

  2. 使用阿里云 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 = "";    private static final String accessKeyId = "";    private static final String 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 = "";    private static String 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 = "";    private static String 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 服务开发后端存储附件的大致流程,在代码中需要根据需求进行详细的调整和优化。

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

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

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

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

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

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

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

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

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

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

  4. 当操作完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 ossClientPool = new ArrayBlockingQueue(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 list = new ArrayList();        ossClientPool.drainTo(list);        for (OSSClient ossClient : list) {            ossClient.shutdown();        }    }}

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

  5. 在使用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 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 = "";    String accessKeyId = "";    String accessKeySecret = "";    // 创建连接池    OSSClientPool pool = new OSSClientPool(endpoint, accessKeyId, accessKeySecret, Protocol.HTTPS, 10, TimeUnit.MINUTES.toMillis(5));    try (OSS client = pool.getClient()) {        // 使用客户端对象进行操作        client.putObject("", "", "");    }    // 关闭连接池    pool.close();}

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