谈谈存储系统
文件存储是开发中常常用到的。下面我将对如下存储系统进行说明:
- 阿里云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