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. 《OKR工作法》| 一次说太多等于什么都没说

    在<OKR工作法>中,作者用汉娜和杰克一起创造TeaBee的故事来为我们讲解OKR可以解决的问题以及如何去实践OKR.给我印象最深的他们用OKR目标管理失败的时候埋怨这种管理方法是有问题的 ...

  2. MySQL中SUM和COUNT的区别

    COUNT:是对记录进行汇总,即计数 SUM:是对符合条件的数值列字段进行求和 原表数据如下: 1,当在where子句中使用Price>25时, COUNT函数返回的是符合条件的记录,SUM函数 ...

  3. luogu P2353 背单词

    二次联通门 : luogu P2353 背单词 一眼看过去, 卧槽,AC自动机板子题 写完后T成SB 卧槽10^6 做个篮子啊 重构思路... 恩..Hash + 莫队... 恶心啊.. 找xxy d ...

  4. python 获取文件本身的绝对路径

    tester.py: import os print (os.path.dirname(__file__)) print (os.path.abspath(__file__)) print (os.p ...

  5. LSF 作业系统常用命令

    LSF(Load Sharing Facility)是一个被广泛使用的作业管理系统,具有高吞吐.配置灵活的优点.通过 LSF 集中监控和调度,可以充分利用计算机的CPU.内存.磁盘等资源. bqueu ...

  6. 提前体验让人"回归Windows怀抱"的Windows Terminal

    前言 在一年一度的微软开发者大会Build 2019登场的Windows Terminal饱受好评,大家对其也是充满了兴趣和热情,程序员的朋友圈都被微软发布的最新终端 windows Terminal ...

  7. PowerDesigner应用01 逆向工程之配置数据源并导出PDM文件

    物理数据模型(Physical Data Model)PDM,提供了系统初始设计所需要的基础元素,以及相关元素之间的关系:数据库的物理设计阶段必须在此基础上进行详细的后台设计,包括数据库的存储过程.操 ...

  8. 权重轮询调度算法(WeightedRound-RobinScheduling)

    权重轮询调度算法(WeightedRound-RobinScheduling)-Java实现 ----参考Nginx中负载均衡算法实现 这里主要参考这篇文章的实现: Nginx 负载均衡-加权轮询策略 ...

  9. 范仁义html+css课程---11、html补充知识

    范仁义html+css课程---11.html补充知识 一.总结 一句话总结: 小于号(<):< 大于号(>):> 空格:  二.html 字符实体 1.小于号(<)和大 ...

  10. 在HPC的节点上使用jupyter notebook

    投递任务,注意资源设置 #!/bin/bash #SBATCH --nodes=1 #SBATCH --ntasks=1 #SBATCH --cpus-per-task=1 #SBATCH --mem ...