zoukankan      html  css  js  c++  java
  • 谈谈存储系统

    文件存储是开发中常常用到的。下面我将对如下存储系统进行说明:

    • 阿里云OSS
    • ftp
    • Java常规存储

    一、阿里云OSS

    阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。其数据设计持久性不低于99.999999999%,服务设计可用性不低于99.99%。具有与平台无关的RESTful API接口,您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。

    您可以使用阿里云提供的API、SDK接口或者OSS迁移工具轻松地将海量数据移入或移出阿里云OSS。数据存储到阿里云OSS以后,您可以选择标准类型(Standard)的阿里云OSS服务作为移动应用、大型网站、图片分享或热点音视频的主要存储方式,也可以选择成本更低、存储期限更长的低频访问类型(Infrequent Access)和归档类型(Archive)的阿里云OSS服务作为不经常访问数据的备份和归档。
    (引自官方文档,官方文档可参考:https://help.aliyun.com/video_detail/39708.html?spm=5176.10695662.1996646101.searchclickresult.6ce04d08gnXv2N)

    使用步骤(均来自官方文档)

    1.加入Maven依赖

     <dependency>
        <groupId>com.aliyun.oss</groupId>
        <artifactId>aliyun-sdk-oss</artifactId>
        <version>2.8.3</version>
    </dependency>

    2.编写上传类

    import java.io.ByteArrayInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.InputStream;
    
    import com.aliyun.oss.OSSClient;
    import com.aliyun.oss.model.GetObjectRequest;
    
    public class UploadOSS {
        //上传文件(以上传图片为例)
        public static void main(String[] args) throws Exception {
            // Endpoint以杭州为例,其它Region请按实际情况填写。
            String endpoint = "http://oss-cn-beijing.aliyuncs.com";
            // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
            String accessKeyId = "访问密钥ID";
            String accessKeySecret = "访问密钥";
            String bucketName = "challenegertech";
            String objectName="AdminLTE.PNG";
            // 创建OSSClient实例。
            OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
    
            // 上传文件流。
            InputStream inputStream = new FileInputStream("C://Users//eluzhu//Pictures//AdminLTE.PNG");
            ossClient.putObject(bucketName,objectName, inputStream);
    
            // 关闭OSSClient。
            ossClient.shutdown();
        }
    }

    或许有人问,不太明白上述参数是从那里获取到的,这里我建议去官方文档上面看,如下:
    https://help.aliyun.com/video_detail/39708.html?spm=5176.10695662.1996646101.searchclickresult.6ce04d08gnXv2N

    像腾讯云、百度云、七牛云等存储系统,其实和阿里云相差并不大,都可以用。我公司其中一个项目用到的存储系统就是腾讯云。像我之前研究的一个jeesite开源项目,其存储系统主要用的是七牛云。

    关于腾讯云、百度云、七牛云详细对比,感兴趣的可以参考这篇文章腾讯云、七牛云、阿里云存储对比

    二、ftp

    由于我主要参考wordpress,所以关于存储那块,我也准备采用ftp的方式。
    关于FTP服务搭建可以参考如下文章:
    FTP服务搭建(以CentOS7为例)
    FTP服务搭建(以Ubuntu16.04为例)

    关于Java当中如何使用FTP上传下载文件,大家可以参考如下步骤:

    1.添加maven依赖

    <dependency>
        <groupId>commons-net</groupId>
        <artifactId>commons-net</artifactId>
        <version>3.3</version>
    </dependency>

    2.添加配置类(主要是ftp配置相关信息)

    package com.blog.springboot.config;
    
    public class FtpConfig {
        private int port; //ftp端口
        private String ftpLoginName; //ftp服务器登录账户
        private String ftpLoginPwd; //ftp服务器登录密码
        private String hostName; //ftp主机ip
        private String basePath; //ftp文件基础路径
        private String baseImgUrl; //ftp前端界面图片访问路径
    
        public String getBasePath() {
            return basePath;
        }
        public void setBasePath(String basePath) {
            this.basePath = basePath;
        }
        public String getBaseImgUrl() {
            return baseImgUrl;
        }
        public void setBaseImgUrl(String baseImgUrl) {
            this.baseImgUrl = baseImgUrl;
        }
        public int getPort() {
            return port;
        }
        public void setPort(int port) {
            this.port = port;
        }
        public String getFtpLoginName() {
            return ftpLoginName;
        }
        public void setFtpLoginName(String ftpLoginName) {
            this.ftpLoginName = ftpLoginName;
        }
        public String getFtpLoginPwd() {
            return ftpLoginPwd;
        }
        public void setFtpLoginPwd(String ftpLoginPwd) {
            this.ftpLoginPwd = ftpLoginPwd;
        }
        public String getHostName() {
            return hostName;
        }
        public void setHostName(String hostName) {
            this.hostName = hostName;
        }
    
    }

    3.添加工具类并编写main方法测试

    package com.blog.springboot.utils;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.SocketException;
    import java.util.UUID;
    
    import org.apache.commons.net.ftp.FTP;
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.net.ftp.FTPFile;
    import org.apache.commons.net.ftp.FTPReply;
    
    import com.blog.springboot.controller.AbstractController;
    
    public class FtpUtils extends AbstractController{
        FTPClient ftpClient=new FTPClient();
    
        /**
         *
         * @param hostName ftp服务器主机名ip
         * @param port  ftp服务器连接断口
         * @param loginName  ftp服务器登录名
         * @param loginPwd  ftp服务器登录密码
         */
        public void FtpLogin(String hostName,int port,String loginName,String loginPwd){
            try {
                ftpClient.connect(hostName, port);
                ftpClient.login(loginName, loginPwd);
                int reply=ftpClient.getReplyCode();   //判断ftp是否正确连接,返回状态码值在200~300之间表示正确连接
                logger.info("reply:"+reply);
                if(!FTPReply.isPositiveCompletion(reply)){
                    ftpClient.disconnect();
                }
            } catch (SocketException e) {
                logger.error("socket错误:",e);
            } catch (IOException e) {
                logger.error("io错误:",e);
            }
        }
    
        /**
         * 断开ftp连接
         */
        public void closeConnection(){
            if(ftpClient.isConnected()){
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                    logger.error("io错误:",e);
                }
            }
        }
    
        /**
         * 修改文件名为uuid开头避免文件名重复
         * @param fileName 获取上传的文件名
         * @return 新的文件名
         */
        public String getFileSuffName(String fileName){
            File file=new File(fileName);
            String oldFileName=file.getName();
            String suffixFileName=oldFileName.substring(oldFileName.lastIndexOf(".")+1);
    
            String uuid=UUID.randomUUID().toString().replace("-","");
            String newFileName=uuid+"."+suffixFileName;
    
            return newFileName;
        }
    
        /**
         * 上传文件
         * @param filePath 文件路径,如 2019/02/23
         * @param basePath 基础路径  /home/ftpUpFile/
         * @param is 文件流
         * @param fileName 文件名称
         * @return
         */
        public boolean uploadFile(String filePath,String basePath,InputStream is,String fileName){
            boolean flag=false;
            try {
                if(!ftpClient.changeWorkingDirectory(basePath+filePath)){
                    String[] dirs=filePath.split("/");
                    String tempPath=basePath;
                    for(String dir:dirs){
                        if(null==dir || "".equals(dir))continue;
                        tempPath+="/"+dir;
                        if(!ftpClient.changeWorkingDirectory(tempPath)){
                            if(!ftpClient.makeDirectory(tempPath)){
                                return flag;
                            }else{
                                ftpClient.changeWorkingDirectory(tempPath);
                            }
                        }
                    }
                }
                ftpClient.setFileType(FTP.BINARY_FILE_TYPE);//设置文件为二进制流
                if(!ftpClient.storeFile(fileName, is)){ //上传文件
                    return flag;
                }
                is.close();
                ftpClient.logout();
                flag=true;
            } catch (IOException e) {
                logger.error("io错误:",e);
            }finally{
                closeConnection();
            }
            return flag;
        }
    
        /**
         * Description: 从FTP服务器下载文件
         * @param host FTP服务器hostname
         * @param port FTP服务器端口
         * @param username FTP登录账号
         * @param password FTP登录密码
         * @param remotePath FTP服务器上的相对路径
         * @param fileName 要下载的文件名
         * @param localPath 下载后保存到本地的路径
         * @return
         */
        public  boolean downloadFile(String remotePath,String fileName, String localPath) {
            boolean result = false;
            try {
                ftpClient.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录
                FTPFile[] files = ftpClient.listFiles();
                for (FTPFile ff : files) {
                    if (ff.getName().equals(fileName)) {
                        File localFile = new File(localPath + "/" + ff.getName());
    
                        OutputStream is = new FileOutputStream(localFile);
                        ftpClient.retrieveFile(ff.getName(), is);
                        is.close();
                    }
                }
                ftpClient.logout();
                result = true;
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                closeConnection();
            }
            return result;
        }
    
    
        public static void main(String[] args) throws FileNotFoundException {
            FtpUtils f = new FtpUtils();
            f.FtpLogin("192.168.126.130", 21, "ftp", "ftp.");
    
            FileInputStream in=new FileInputStream(new File("C://Users//test//Downloads//AdminLTE.PNG"));
            f.uploadFile("image", "/home/ftpuser/ftp", in, "AdminLTE.PNG");
        }
    }

    三、Java常规存储

    常规存储,一般情况是存在tomcat某个文件夹下,或者是将文件以流的形式写入数据库对应的表中(通常不建议这么做,极大的损耗数据库的I/O流和存储容量)。
    下面链接大家可以做个参考:
    Java上传文件到tomcat:https://blog.csdn.net/qq_41463655/article/details/84145602
    Java常见三种上传文件方式(其中有包括流的方式):https://blog.csdn.net/weixin_39640122/article/details/80244527

  • 相关阅读:
    [转]基于S2SH框架的项目—antlr-2.7.2.jar包冲突问题
    输入法那没有小键盘的图标解决方法
    Chrome百度不显示中文字体
    转:数据库范式(1NF 2NF 3NF BCNF)
    转:海明纠错码
    奇阶魔方阵
    字符串的模式匹配
    红黑树
    排序算法总结
    关于面试总结9-接口测试面试题
  • 原文地址:https://www.cnblogs.com/youcong/p/10422360.html
Copyright © 2011-2022 走看看