热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:图片存储方案七牛云存储

本文由编程笔记#小编为大家整理,主要介绍了图片存储方案-七牛云存储相关的知识,希望对你有一定的参考价值。
本文由编程笔记#小编为大家整理,主要介绍了图片存储方案-七牛云存储相关的知识,希望对你有一定的参考价值。






简介


在我们实际的项目中,经常会将服务器进行划分,比如:专门运行我们程序的应用服务器、专门运行我们数据库的数据库服务器、还有负责文件存储的文件服务器、负责视频存储的服务器。


这些服务器组成我们的所有服务、各司其职,这样划分的目的相比大家也知道,减轻一台服务器服务器的压力。


当用户请求我们应用应用服务器的时候,由我们的应用再分别访问我们数据库服务器、文件存储服务器等,最后将请求的资源返回给我们的用户,这样构成整个应用的请求过程:



图片存储方案-七牛云存储

我们今天要讲的就是图片存储,图片储存的方案有很多,比如:可以使用Fastdfs或者HDFS、使用nginx搭建图片存储服务器。


现在比较流行的就是「云存储」,使用「阿里云、七牛云」等。这一节我们使用七牛云做了实例讲解。


七牛云入门


图片存储方案-七牛云存储注册完后直接登陆,登陆后右上角有一个「管理控制平台」,点击管理控制平台的产品首页,还要进行「实名认证才能创建对象存储存储空间」,实名认证后点击对象存储的「立即添加」:


图片存储方案-七牛云存储点击立即添加后来到对象存储空间的创建页面,点击「新建空间」图片存储方案-七牛云存储


创建存储空间后可以看见自己创建的空间的详细信息,并且可以创建多个存储空间,每一个存储空间相互独立,不会互相干扰。


七牛云提供了多种的方式操作对象存储服务,我们这里使用的是Java SDK方式,具体的使用可以在开发者中心查看:



图片存储方案-七牛云存储


图片存储方案-七牛云存储

Java SDK开发文档里面有详细的操作的API说明,以及要引入的依赖坐标。



图片存储方案-七牛云存储

代码实战


首先在自己的项目中引入七牛云的依赖坐标:



  com.qiniu
  qiniu-java-sdk
  7.2.0


从Java SDK的操作文档中,简单操作文档的上传的示例代码如下:


//构造一个带指定 Region 对象的配置类
Configuration cfg = new Configuration(Region.region0());
//...其他参数参考类注释
UploadManager uploadManager = new UploadManager(cfg);
//...生成上传凭证,然后准备上传,填写AK和SK以及buket name
String accessKey = "your access key";
String secretKey = "your secret key";
String bucket = "your bucket name";
//文件路径,如果是Windows情况下,格式是 D:\qiniu\test.png
String localFilePath = "/home/qiniu/test.png";
//默认不指定key的情况下,以文件内容的hash值作为文件名
String key = null;
Auth auth = Auth.create(accessKey, secretKey);
String upToken = auth.uploadToken(bucket);
try {
    Response response = uploadManager.put(localFilePath, key, upToken);
    //解析上传成功的结果
    DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
    System.out.println(putRet.key);
    System.out.println(putRet.hash);
} catch (QiniuException ex) {
    Response r = ex.response;
    System.err.println(r.toString());
    try {
        System.err.println(r.bodyString());
    } catch (QiniuException ex2) {
        //ignore
    }
}

上面的是根据文件路径来上传文件,还支持字节数组上传到空间中:


//构造一个带指定 Region 对象的配置类
Configuration cfg = new Configuration(Region.region0());
//...其他参数参考类注释
UploadManager uploadManager = new UploadManager(cfg);
//...生成上传凭证,然后准备上传
String accessKey = "your access key";
String secretKey = "your secret key";
String bucket = "your bucket name";
//默认不指定key的情况下,以文件内容的hash值作为文件名
String key = null;
try {
    byte[] uploadBytes = "hello qiniu cloud".getBytes("utf-8");
    Auth auth = Auth.create(accessKey, secretKey);
    String upToken = auth.uploadToken(bucket);
    try {
        Response response = uploadManager.put(uploadBytes, key, upToken);
        //解析上传成功的结果
        DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
        System.out.println(putRet.key);
        System.out.println(putRet.hash);
    } catch (QiniuException ex) {
        Response r = ex.response;
        System.err.println(r.toString());
        try {
            System.err.println(r.bodyString());
        } catch (QiniuException ex2) {
            //ignore
        }
    }
} catch (UnsupportedEncodingException ex) {
    //ignore
}

以及删除上传的文件:


//构造一个带指定 Region 对象的配置类
Configuration cfg = new Configuration(Region.region0());
//...其他参数参考类注释
String accessKey = "your access key";
String secretKey = "your secret key";
String bucket = "your bucket name";
String key = "your file key";
Auth auth = Auth.create(accessKey, secretKey);
BucketManager bucketManager = new BucketManager(auth, cfg);
try {
    bucketManager.delete(bucket, key);
} catch (QiniuException ex) {
    //如果遇到异常,说明删除失败
    System.err.println(ex.code());
    System.err.println(ex.response.toString());
}

上面有提到比较关键的信息,因为使用七牛云服务要进行认证,上面有三个数据「AK、SK和bucket name」,AK和SK也就是AccessKey/SecretKey


AK和SK这个信息中可以在如下的页面获取,bucket name也就是你在创建存储空间的时候填信息的名称:




有了这些信息,我们可以将上面的代码封装成自己的工具类:


public class QiniuUtils {
    // 填写你的accessKey值
    public  static String accessKey = "your accessKey";
     // 填写你的secretKey 值
    public  static String secretKey = "your secretKey ";
    // 填写你的 bucket name值
    public  static String bucket = "your bucket name";
    /**
     * 上传文件
     * @param filePath 文件路径
     * @param fileName 文件名
     */
    public static void uploadFile(String filePath,String fileName){
        Configuration cfg = new Configuration(Zone.zone0());
        UploadManager uploadManager = new UploadManager(cfg);
        Auth auth = Auth.create(accessKey, secretKey);
        String upToken = auth.uploadToken(bucket);
        try {
            Response response = uploadManager.put(filePath, fileName, upToken);
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
        } catch (QiniuException ex) {
            Response r = ex.response;
            try {
                System.err.println(r.bodyString());
            } catch (QiniuException ex2) {
                //ignore
            }
        }
    }
    /**
     * 上传文件
     * @param bytes 文件字节数组
     * @param fileName 文件名
     */
    public static void uploadFile(byte[] bytes, String fileName){
        Configuration cfg = new Configuration(Zone.zone0());
        UploadManager uploadManager = new UploadManager(cfg);
        String key = fileName;
        Auth auth = Auth.create(accessKey, secretKey);
        String upToken = auth.uploadToken(bucket);
        try {
            Response response = uploadManager.put(bytes, key, upToken);
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
        } catch (QiniuException ex) {
            Response r = ex.response;
            try {
                System.err.println(r.bodyString());
            } catch (QiniuException ex2) {
                //ignore
            }
        }
    }
    /**
     * 删除文件
     * @param fileName 文件名
     */
    public static void deleteFile(String fileName){
        Configuration cfg = new Configuration(Zone.zone0());
        String key = fileName;
        Auth auth = Auth.create(accessKey, secretKey);
        BucketManager bucketManager = new BucketManager(auth, cfg);
        try {
            bucketManager.delete(bucket, key);
        } catch (QiniuException ex) {
            System.err.println(ex.code());
            System.err.println(ex.response.toString());
        }
    }
}

然后写一个接口作为文件上传的测试类:


@Autowired 
private JedisPool jedisPool; //图片上传 
@RequestMapping("/uploadImage"
public ResponseResult upload(@RequestParam("imgFile")MultipartFile imgFile){ 
 try{
     //获取原始文件名 
  String originalFilename = imgFile.getOriginalFilename(); 
  //获取图片名后缀 
  int lastIndexOf = originalFilename.lastIndexOf("."); 
  String suffix = originalFilename.substring(lastIndexOf ‐ 1); 
  //使用UUID生成图片名,防止名称一样
  String fileName = UUID.randomUUID().toString() + suffix; QiniuUtils.uploadFile(imgFile.getBytes(),fileName); //图片上传成功 
  ResponseResult result = new ResponseResult (ResponseConstant.UPLOAD_SUCCESS,"上传成功"); 
  result.setData(fileName); 
  //将上传图片名称存入Redis,基于Redis的Set集合存储 
  jedisPool.getResource().sadd(ImageConstant.ALl_PIC_RESOURCES,fileName ); 
  return result; 
 }catch (Exception e){ 
  e.printStackTrace(); //图片上传失败 
  return new ResponseResult (ResponseConstant.UPLOAD_FAIL,"文件上传失败"); 
 } 
}

这里在作为图片上传的时候使用Redis的set集合进行缓存,这样做的目的就是,用户自己点击上传文件后,填写完信息,但是后面就有可能包填写的消息取消掉。


这样这些图片就会成为我们的垃圾图片,若是没有存储这些图片的信息,从此也找不到这些图片,这样这些垃圾图片就会占用空间。


我们的解决方案就是,先把所有的这些图片还存在Redis的一个Set集合中,叫做ALl_PIC_RESOURCES


然后把上传成功的图片还存在Redis的另一个Set集合中叫做L:SUCCESS_PIC_RESOURCES


最后系统起一个定时任务,定期清理掉ALl_PIC_RESOURCESL:SUCCESS_PIC_RESOURCES差值的图片数据,清理时间可以设置在晚上凌晨,这样对系统的性能影响就不会那么大。


定时任务可以选用Quartz,我相信这个定时任务框架应该很多人都用过,在项目中直接引入依赖坐标:



     org.quartz-scheduler
     quartz
 

 
     org.quartz-scheduler
     quartz-jobs
 


具体的定时任务的配置可以自行百度一下,这里只给出,定时任务清理图片的方法:


public void deleteImage(){
        //比较两个Set集合得到差集,得到无效的图片名称集合
        Set imageSet = redisTemplate.opsForSet().difference("ALl_PIC_RESOURCES""L:SUCCESS_PIC_RESOURCES");
        for (String imageName : imageSet ) {
            //删除图片
            QiniuUtils.deleteFileFrom(imageName );
            //删除缓存中无用的图片
            redisTemplate.boundSetOps("ALl_PIC_RESOURCES").remove(imageName );
        }
    }

好了,今天的实例讲解就到这里了,觉得有帮助的求个三连,我们下期再见。






推荐阅读
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 20211101CleverTap参与度和分析工具功能平台学习/实践
    1.应用场景主要用于学习CleverTap的使用,该平台主要用于客户保留与参与平台.为客户提供价值.这里接触到的原因,是目前公司用到该平台的服务~2.学习操作 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 如何搭建Java开发环境并开发WinCE项目
    本文介绍了如何搭建Java开发环境并开发WinCE项目,包括搭建开发环境的步骤和获取SDK的几种方式。同时还解答了一些关于WinCE开发的常见问题。通过阅读本文,您将了解如何使用Java进行嵌入式开发,并能够顺利开发WinCE应用程序。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
author-avatar
牛牛的牛66_674
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有