谈谈存储系统

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

  • 阿里云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

posted @ 2019-02-23 13:15  挑战者V  阅读(533)  评论(0编辑  收藏  举报