分布式文件系统FastDFS 技术整理

1、FastDFS1.1、了解基础概念1.1.1、什么是分布式文件系统?

  • 全称:Distributed File System,即简称的DFS
  • 这个东西可以是一个软件,也可以说是服务器,和Tomcat差不多,即相当于软件也相当于是服务器,这个软件就是用来管理文件的
  • 这个软件所管理的文件通常不是在一个服务器节点上,而是在多个服务器节点上
  • 服务器节点通过网络相连构成一个庞大的文件存储服务器集群,这些服务器都用于存储文件资源,通过分布式文件系统来管理这些服务器上的文件

 
1.1.2、传统文件系统 和 分布式文件系统对比传统文件系统
分布式文件系统FastDFS 技术整理

文章插图
 
  • 缺点所有的文件都存放在一台计算机中,如果这台计算机挂彩了,那么就会导致整个服务不可用( 文件不能上传和下载了 )如果这台计算机磁盘损坏了,那么会丢失所有的文件这台计算机的磁盘空间非常有限,很容易到达磁盘的上限,导致无法上传文件

 
  • 回顾玩servlet时的文件上传和下载
  • 文件上传
    • 假如前端轰html写法是如下的样子:
  • <div id="image"> <label for="">标题图片:</label> <input type="file" id="file" name="file" > <img src=https://www.isolves.com/it/rj/jy/2022-06-06/"" width="100px" height="150px">
  • JS写法如下:
  • // 当图片发生改变时 —— 也就是用户点击file框,上传文件时 $("#file").on( 'change' , function () { // 创建一个FormData空对象,就相当于是伪造了一个form表单 let formData = new FormData(); // 这个FromData对象就用来装文件内容 // 文件的files属性本质是个数组 let files = $("#file").prop("files"); formData.Append("upFile" , files[0] ); $.ajax( { url: '/ajax/upload.do', type: 'post', data: formData, dataType: 'json', cache: false, // 上传文件不需要缓存 contentType: false, // 不需要对内容类型进行处理 因为内容是一个FormData对象 processData: false, // 不需要对数据进行处理,因为上面的data是一个FormData对象 // 后台返回的格式 : // { "errno":"0" , "data":[ {"alt":"1633528500498.jpg" , "url":"/upload/2021-10-06/1633528500498.jpg"} ] } success: function (info) { info.data.forEach( function (data) { // $("#image img").remove(); // $("#image").append( ' <img src=" '+data.url+' " alt="" width="100px" height="150px"> ' ) /* 注掉的这种是:html中没有img标签时使用 因为:使用下面这种方法的情景是 —— 页面本来就有一个img框( 即:初始页面上这个file本身有一张图片 ),所以下面这种可以做到图片改变时把图片的路径换掉,也就是图片渲染( 也是数据回填 的思想 ) 但是:如果页面一开始file的位置是不应该有图片的,是后面用户选了之后才出现图片预览效果,那么:就使用注释掉的这种方法:追加 */ $("#image img").attr("src" , data.url ); }); } } ); })
    • 那么后端的low代码如下:
  • import com.alibaba.fastjson.JSON; import JAVAx.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; import java.io.File; import java.io.IOException; import java.time.LocalDate; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; // @MultipartConfig 注解就是文件注解,要获取前端的文件信息,必须加这个注解,不然做的所有事情都是无用功 @MultipartConfig @WebServlet("/ajax/upload.do") public class UploadServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { /* * 想要构建的是这么一个玩意儿 * "errno":0 data:[ { url:"图片地址“ } , { alt:"图片说明“ } , { href:"null" } ] * * */ ArrayList<Object> list = new ArrayList<>(); Collection<Part> parts = req.getParts(); // 这是获取前台上传的文件 for (Part part : parts) { // 先构建 data:[ { } , { } ]中的[ { } , { } ] // 获取文件的全路径 // 但是:不同浏览器的这个全路径都不一样,所以需要截取从而自定义文件名 String filePath = part.getSubmittedFileName(); // System.out.println(filePath); // 截取文件的后缀名 int subFileName = filePath.lastIndexOf("."); String fileSuffix = filePath.substring(subFileName); // 自己给文件重新定义一个名字,并规定存放的地方 String timeStr = LocalDate.now().toString(); // 获取当前项目的一个指定文件夹名字,用来保存文件 注意:getRealPath这是获取的当前项目的全路径,即:从盘符开始的路径 String proPathName = this.getServletContext().getRealPath("/upload/" + timeStr ); File file = new File(proPathName); if ( !file.exists() ){ file.mkdirs(); } // 拼接文件后缀名并保存文件 long timeStamp = new Date().getTime(); part.write(proPathName + "/" + timeStamp + fileSuffix ); HashMap<String, String> map = new HashMap<>(); map.put( "url" , "/upload/" + timeStr + "/" + timeStamp + fileSuffix ); map.put( "alt" , timeStamp + fileSuffix ); map.put( "href" , null ); list.add(map); } // 再构建"errno":0 data:[ { url:"图片地址“ } , { alt:"图片说明“ } , { href:"null" } ] HashMap<String, Object> map = new HashMap<>(); map.put("errno", "0"); map.put("data", list); resp.getWriter().print( JSON.toJSONString(map) ); } }


    推荐阅读