1、文件上传简单流程分析图:

2、Fastdfs介绍:

  Fastdfs由两个角色组成:

    Tracker(集群):调度(帮你找到有空闲的Storage)

    Storage(集群):文件存储(帮你保存文件或获取需要的文件)

  流程:

    1.Storage和tracker 发送心跳连接。

    2.客户端请求tracker,tracker调度一个Storage,返回Storage的ip和端口。

    3.客户端请求Storage,上传文件。

    4.Storage保存文件,生成file_id,并返回。

    5.客户端接收到file_id并保存。

3、上传下载流程图:

上传:

下载:

4、Fastdfs上传具体实现步骤:

  1. 在服务器上搭建好fastdfs环境:这个由运维人员操作,开发人员无需关心。

  2. 在本地maven仓库导入fastdfs的jar包(该jar包在maven中央仓库中没有,无法通过idea自动下载,只能手动导入到本地仓库中去)

  jar包下载地址(fastdfs_client_v1.20.jar):https://sourceforge.net/projects/fastdfs/files/Java%20Client%20API%20Library/Java%20Client%20Library%20V1.20%20%28compiled%20by%20JDK%201.6%29/fastdfs_client_v1.20.jar/download?use_mirror=liquidtelecom&download=&failedmirror=jaist.dl.sourceforge.net

  导入本地仓库:

  在jar包所在的目录打开cmd,然后输入以下命令,执行后即可在maven本地仓库导入jar包并在cmd显示出jar包在仓库中的路径。

mvn install:install-file -DgroupId=org.csource.fastdfs -DartifactId=fastdfs  -Dversion=1.2 -Dpackaging=jar -Dfile= fastdfs_client_v1.20.jar

  3. 项目中引入

<dependency>
<groupId>org.csource.fastdfs</groupId>
<artifactId>fastdfs</artifactId>
<version>1.2</version>
</dependency>

  

  4、项目中引入以下工具类:

fdfs_client.conf  文件(用于保存指向 tracker 的IP+端口(默认)):

tracker_server=172.16.2.274:

工具类:

import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer; public class FastDfsApiOpr { public static String CONF_FILENAME = FastDfsApiOpr.class.getResource("/fdfs_client.conf").getFile(); /**
* 上传文件
* @param file
* @param extName
* @return
*/
public static String upload(byte[] file,String extName) { try {
ClientGlobal.init(CONF_FILENAME); TrackerClient tracker = new TrackerClient();
TrackerServer trackerServer = tracker.getConnection();
StorageServer storageServer = null; StorageClient storageClient = new StorageClient(trackerServer, storageServer);
NameValuePair nvp [] = new NameValuePair[]{
new NameValuePair("age", "18"),
new NameValuePair("sex", "male")
};
String fileIds[] = storageClient.upload_file(file,extName,nvp); System.out.println(fileIds.length);
System.out.println("组名:" + fileIds[0]);
System.out.println("路径: " + fileIds[1]);
return "/"+fileIds[0]+"/"+fileIds[1]; } catch (Exception e) {
e.printStackTrace();
return null;
}
} /**
* 下载文件
* @param groupName
* @param fileName
* @return
*/
public static byte[] download(String groupName,String fileName) {
try { ClientGlobal.init(CONF_FILENAME); TrackerClient tracker = new TrackerClient();
TrackerServer trackerServer = tracker.getConnection();
StorageServer storageServer = null; StorageClient storageClient = new StorageClient(trackerServer, storageServer);
byte[] b = storageClient.download_file(groupName, fileName);
return b;
} catch (Exception e) {
e.printStackTrace();
return null;
}
} // @Test
// public void testGetFileInfo(){
// try {
// ClientGlobal.init(conf_filename);
//
// TrackerClient tracker = new TrackerClient();
// TrackerServer trackerServer = tracker.getConnection();
// StorageServer storageServer = null;
//
// StorageClient storageClient = new StorageClient(trackerServer, storageServer);
// FileInfo fi = storageClient.get_file_info("group1", "M00/00/00/wKgRcFV_08OAK_KCAAAA5fm_sy874.conf");
// System.out.println(fi.getSourceIpAddr());
// System.out.println(fi.getFileSize());
// System.out.println(fi.getCreateTimestamp());
// System.out.println(fi.getCrc32());
// } catch (Exception e) {
// e.printStackTrace();
// }
// } // @Test
// public void testGetFileMate(){
// try {
// ClientGlobal.init(conf_filename);
//
// TrackerClient tracker = new TrackerClient();
// TrackerServer trackerServer = tracker.getConnection();
// StorageServer storageServer = null;
//
// StorageClient storageClient = new StorageClient(trackerServer,
// storageServer);
// NameValuePair nvps [] = storageClient.get_metadata("group1", "M00/00/00/wKgRcFV_08OAK_KCAAAA5fm_sy874.conf");
// for(NameValuePair nvp : nvps){
// System.out.println(nvp.getName() + ":" + nvp.getValue());
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
// } /**
* 删除文件
* @param groupName
* @param fileName
*/
public static void delete(String groupName,String fileName){
try {
ClientGlobal.init(CONF_FILENAME); TrackerClient tracker = new TrackerClient();
TrackerServer trackerServer = tracker.getConnection();
StorageServer storageServer = null; StorageClient storageClient = new StorageClient(trackerServer,
storageServer);
int i = storageClient.delete_file(groupName,fileName);
System.out.println( i==0 ? "删除成功" : "删除失败:"+i);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("删除异常,"+e.getMessage());
}
}
}

  5、在contorller中使用:

@RestController
public class FileController { /**
* 文件上传 MultipartFile 是SpringMVC封装好的API方便操作上传的文件的
* @param file
* @return
*/
@PostMapping("/fastdfs")
public AjaxResult upload(MultipartFile file){ try {
//获取文件的扩展名
String filename = file.getOriginalFilename();
String extName = filename.substring(filename.lastIndexOf(".")+1);
String file_id = FastDfsApiOpr.upload(file.getBytes(), extName);
return AjaxResult.me().setSuccess(true).setMessage("上传成功!").setRestObj(file_id);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.me().setSuccess(false).setMessage("上传失败!"+e.getMessage());
} } /**
* 删除文件
* @param file_id
* @return
*/
@DeleteMapping("/fastdfs")
public AjaxResult delete(String file_id){
try {
// /group1/M00/00/01/rBACgF1euQiAEdrcAACbjnUEnrE193.jpg file_id = file_id.substring(1);// group1/M00/00/01/rBACgF1euQiAEdrcAACbjnUEnrE193.jpg String groupName = file_id.substring(0, file_id.indexOf("/")); String fileName = file_id.substring(file_id.indexOf("/")+1); FastDfsApiOpr.delete(groupName, fileName); return AjaxResult.me().setSuccess(true).setMessage("删除成功!"); } catch (Exception e) {
e.printStackTrace(); return AjaxResult.me().setSuccess(false).setMessage("删除失败!"); } } }

  5.1控制文件上传的大小

    为了解决有些文件因大于默认上传文件大小的而无法上传的问题,可以在网关模块和引用Fastdfs的controller所在的模块的启动类上加上如下代码:

 /**
* 文件大小上传配置
* @return
*/
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
//单个文件最大
factory.setMaxFileSize("10240KB"); //KB,MB
/// 设置总上传数据总大小
factory.setMaxRequestSize("102400KB");
return factory.createMultipartConfig();
}

  6、前端页面代码

          <el-form-item label="logo">
<el-upload
class="upload-demo"
action="http://localhost:6001/services/common/fastdfs"
:file-list="addForm.logoList"
list-type="picture"
:on-success="logoUploadSuccess"
:before-upload="handleBeforeUpload"
:on-remove="handleLogoRemove">
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
</el-form-item>
methods: {
handleLogoRemove(file, fileList){
//file 删除的文件
//调用删除文件的接口
let file_id = file.response.restObj
this.$http.delete("/common/fastdfs?file_id="+file_id)
.then(res=>{
let {success,message,restObj} = res.data;
if(success){
//fileList 删除后的文件列表
this.addForm.logoList = fileList;
}else{
this.$message({
message:message,
type:"error"
})
}
})
},
//图片上传之前的回调
handleBeforeUpload(file){
if(this.addForm.logoList.length>0){
this.$message({
message:"只能上传一张图片!",
type:"warning"
})
return false;
}
},
//图片上传成功的回调
logoUploadSuccess(response, file, fileList){
//fileList = [{response:{success:true,restObj:''}},file,file]
this.addForm.logoList = fileList;
console.log(response)
}
}

通过Fastdfs进行文件上传服务(文件和图片的统一处理)的更多相关文章

  1. 构建基于阿里云OSS文件上传服务

    转载请注明来源:http://blog.csdn.net/loongshawn/article/details/50710132 <构建基于阿里云OSS文件上传服务> <构建基于OS ...

  2. SpringMVC文件上传 Excle文件 Poi解析 验证 去重 并批量导入 MYSQL数据库

    SpringMVC文件上传 Excle文件 Poi解析并批量导入 MYSQL数据库  /** * 业务需求说明: * 1 批量导入成员 并且 自主创建账号 * 2 校验数据格式 且 重复导入提示 已被 ...

  3. struts2文件上传,文件类型 allowedTypes

    struts2文件上传,文件类型 allowedTypes 1 '.a' : 'application/octet-stream', 2 '.ai' : 'application/postscript ...

  4. SpringMVC单文件上传、多文件上传、文件列表显示、文件下载(转)

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 本文详细讲解了SpringMVC实例单文件上传.多文件上传.文件列表显示.文件下载. 本文工程 ...

  5. Struts2文件上传--多文件上传(插件uploadify)

    公司需要把以前的Struts2自带的图片上传替换掉,因为不能一个file选择多个文件,本人直接百度搜索图片插件,  貌似就它(uploadify3.2.1)在最前面,也找过很多案例, 其中有不少问题, ...

  6. webAPI文件上传时文件过大404错误的问题

    背景:最近公司有个需求,外网希望自动保存数据到内网,内网有2台服务器可以相互访问,其中一台服务器外网可以访问,于是想在 这台服务器上放个中转的接口.后来做出来以后测试发现没有问题就放线上去了,不顾发现 ...

  7. js插件---IUpload文件上传插件(包括图片)

    js插件---IUpload文件上传插件(包括图片) 一.总结 一句话总结:上传插件找到真正上传位置的代码,这样就可以知道整个上传插件的逻辑了, 找资料还是github+官方 1.如何在js中找到真正 ...

  8. Java FtpClient 实现文件上传服务

    一.Ubuntu 安装 Vsftpd 服务 1.安装 sudo apt-get install vsftpd 2.添加用户(uftp) sudo useradd -d /home/uftp -s /b ...

  9. 在 .NET Core项目中使用UEditor图片、文件上传服务

    在.NET Framework中使用UEditor时,只需要将UEditor提供的后端服务,部署为一个子程序,即可直接使用文件上传相关的服务,但是UEditor官方并未提供.Net Core的项目,并 ...

随机推荐

  1. 在WinDbg中调试时如何查看类/结构对象成员的值

    有时,当您调试应用程序时,会碰巧得到指向类的指针,该类只有几个成员变量,包括结构和其他类对象!如何看待内部类/结构变量成员的值??所以,这是提示.下面是用于演示命令的代码. struct testSt ...

  2. 3.学习SpringMVC注解深入

    一.SpringMVC注解: 1.RequestParam注解: 其中required属性默认为true(必须得传而且传的名字一样),为false时可以不传. 编写jsp代码: <a href= ...

  3. [Python] Python忽略warning警告错误

    Python忽略warning警告错误   1)代码中警告 import warnings warnings.filterwarnings("ignore") 2)忽略命令行下警告 ...

  4. 洛谷P2577 午餐

    题目链接 题意概述:有n个人,第i个人打饭消耗ai时间,离开后吃饭耗费bi时间,将n个人分成两队,合理分配人员使总时间最短并输出总时间. 我们把问题拆分为两个部分.首先是排列顺序,然后是怎么分到两个队 ...

  5. fork,vfork

    转自 http://blog.csdn.net/todd911/article/details/14062103 1.fork函数 一个现有的进程可以调用fork函数创建一个新的子进程. #inclu ...

  6. linux命令之------Mv命令

    Mv命令 1)作用:用来为文件或目录改名/或将文件或目录一如其他位置 2)-i:若指定目录已有同名文件,则先询问是否覆盖旧文件: 3)-f:在mv操作要覆盖某已有的目标文件时,不给任何指示: 4)案例 ...

  7. 洛谷 P5614题解

    吐槽:数据好像有点水,直接枚举到200可以得80 points. 另:我还是太弱了,比赛的时候只有90 points,#7死卡不过去,最后发现是没有判断 \(z_1\) 和 \(z_2\) 的范围-- ...

  8. while循环 运算符和编码

    昨日回顾 1. 初识python python是一门弱类型的解释型高级编程语言 解释器: CPython 官方提供的默认解释器. c语言实现的 PyPy 把python程序一次性进行编译. IPyth ...

  9. linux 系统添加jdk环境变量

    export JAVA_HOME=/usr/local/jdk1..0_79 export JAVA_BIN=$JAVA_HOME/bin export PATH=$PATH:$JAVA_BIN ex ...

  10. java并发编程(八) CAS & Unsafe & atomic

    参考文档:https://www.cnblogs.com/xrq730/p/4976007.html CAS(Compare and Swap) 一个CAS方法包含三个参数CAS(V,E,N).V表示 ...