1. 什么是fastDFS
底层用C语言编写, 开源的分布式文件系统
2. fastDFS是干什么用的
可以保存大量的文件, 目前支持c语言, java语言, php语言的调用
优点: 相比tomcat可以做冗余备份, 防止单台机器硬盘损坏. 数据丢失
它支持负载均衡的功能, 以前是一台机器保存,现在可以是一个集群
支持无限量水平扩展, 一台机器不够, 可以再加N台
3. 怎么用
a. 导入fastDFS的客户端工具包 , 就是一个jar包
b. 编写fastDFS配置文件
c. 编写存储工具类
d. 调用存储工具类,进行存储操作
4.fastDFS原理
原理图
1、
tracker server
:跟踪服务器,主要做调度工作,在访问上起负载均衡的作用。记录
storage server
的状态,是连接
Client
和
storage server
的枢纽。
2、 storage server
:存储服务器(存储节点或数据服务器),文件和
meta data
都保存到该存储服务器上。
3、 group
(
volume
):组,也可以称为卷,
group
是相对storage server
而言的,即资源存放地,一个组可以有多个storage server
,且数据相互备份。同组内服务器上的文件是完全相同的。
4、 meta data
:文件相关属性,以键值对方式存储。
5、
client
:客户端,作为业务请求的发起方,通过专有接口(
API
),使用
TCP/IP
协议与跟踪服务器或存储服务器进行数据交互。
FastDFSUtils
工具类
fdfs_client.conf配置
文件
# connect timeout in seconds # default value is 30s connect_timeout=30 # network timeout in seconds # default value is 30s network_timeout=60 # the base path to store log files base_path=/home/fastdfs # tracker_server can ocur more than once, and tracker_server format is # "host:port", host can be hostname or ip address tracker_server=192.168.200.128:22122 #tracker_server=192.168.101.4:22122 (可以配置多个) #standard log level as syslog, case insensitive, value list: ### emerg for emergency ### alert ### crit for critical ### error ### warn for warning ### notice ### info ### debug log_level=info # if use connection pool # default value is false # since V4.05 use_connection_pool = false # connections whose the idle time exceeds this time will be closed # unit: second # default value is 3600 # since V4.05 connection_pool_max_idle_time = 3600 # if load FastDFS parameters from tracker server # since V4.05 # default value is false load_fdfs_parameters_from_tracker=false # if use storage ID instead of IP address # same as tracker.conf # valid only when load_fdfs_parameters_from_tracker is false # default value is false # since V4.05 use_storage_id = false # specify storage ids filename, can use relative or absolute path # same as tracker.conf # valid only when load_fdfs_parameters_from_tracker is false # since V4.05 storage_ids_filename = storage_ids.conf #HTTP settings http.tracker_server_port=80 #use "#include" directive to include HTTP other settiongs ##include http.conf |
分布式文件工具类
public class FastDFSUtils { /** * 文件上传 * @param pic 文件内容 * @param fileName 文件名称 * @param size 文件大小 * @throws Exception */ public static String uploadPic(byte[] pic,String fileName,long size) throws Exception { // 加载配置文件 ClassPathResource resource = new ClassPathResource("fdfs_client.conf"); ClientGlobal.init(resource.getClassLoader().getResource("fdfs_client.conf").getPath()); // 创建管理节点 TrackerClient trackerClient = new TrackerClient(); // 获取管理节点连接 TrackerServer connection = trackerClient.getConnection(); // 创建存储节点对象 StorageClient1 storageClient1 = new StorageClient1(connection, null); // 获取文件扩展名 String ext = FilenameUtils.getExtension(fileName); // 创建文件描述信息可以为多个 只设置了三个 NameValuePair[] meta_list = new NameValuePair[3]; meta_list[0] = new NameValuePair("fileName", fileName); meta_list[1] = new NameValuePair("FileExt", ext); meta_list[2] = new NameValuePair("FileSize", String.valueOf(size)); // 返回路径file_buff 文件内容, file_ext_name 文件扩展名, meta_list 文件的属性(内容、大小、存放地址..) String path = storageClient1.upload_file1(pic, ext, meta_list); return path; } } |
上传多张图片,可以在输入框加上下面标签 即可完成
上传多张图片前端代码
//上传图片 function uploadPic(){ //上传图片 异步的 Jquery.form.js var options = { url : "/upload/uploadPics.action", type : "post", dataType : "json", success : function(data){ //多图片回显,后台返回json数据 var html = '<tr>' + '<td width="20%" class="pn-flabel pn-flabel-h"></td>' + '<td width="80%" class="pn-fcontent">'; for(var i=0;i<data.length;i++){ html += '<img width="100" height="100" src="' + data[i] + '" />' + '<input type="hidden" name="imgUrl" value="' + data[i] + '"/>' } html += '<a href="javascript:;" class="pn-opt" οnclick="jQuery(this).parents(\'tr\').remove()">删除</a>' + '</td>' + '</tr>'; //回显 $("#tab_2").append(html); } } $("#jvForm").ajaxSubmit(options); } |
通过上面可以跳转
<tbody id="tab_2" style="display: none"> <tr> <td width="20%" class="pn-flabel pn-flabel-h"> <span class="pn-frequired">*</span> 上传商品图片(90x150尺寸):</td> <td width="80%" class="pn-fcontent"> 注:该尺寸图片必须为90x150。 </td> </tr> <tr> <td width="20%" class="pn-flabel pn-flabel-h"></td> <td width="80%" class="pn-fcontent"> <input type="file" οnchange="uploadPic()" name="pics" multiple="multiple"/> </td> </tr> </tbody> |
上传多个图片,传入的参数,前台需要json数据
上传
KindEditor
的图片(
接收
KindeEditor
上传的图片、支持 单张 或多张
(图片的名称不知道也可以接收)
无敌接收
)
1.1
在项目的
webapp/
下添加此
js
注意
:
目前此插件不支持
FireFox
火狐浏览器
,
请使用
Chrom
浏览器访问
1.2
引入
kindeditor-all-min.js
到
head.jsp
页面中
1.3
需要转成
kindEditor
的
textarea
标签
1.4
使用
KindEditor
转换
id
为
productdesc
的
textarea
$(function(){ var tObj; $("#tabs a").each(function(){ if($(this).attr("class").indexOf("here") == 0){tObj = $(this)} $(this).click(function(){ var c = $(this).attr("class"); if(c.indexOf("here") == 0){return;} var ref = $(this).attr("ref"); var ref_t = tObj.attr("ref"); tObj.attr("class","nor"); $(this).attr("class","here"); $(ref_t).hide(); $(ref).show(); tObj = $(this); if(ref == '#tab_3'){ // 编辑器参数 var kingEditorParams = { //指定上传文件参数名称 filePostName : "uploadFile", //指定上传文件请求的url。 uploadJson : '/upload/uploadFck.action', //上传类型,分别为image、flash、media、file dir : "image"//, // width : '1000px', // height : '400px' }; KindEditor.create('#productdesc',kingEditorParams); KindEditor.sync(); } }); }); }); |
1.5
接收
KindEditor
的图片并回调上传路径
UploadController
接收
KindeEditor
上传的图片、支持 单张 或多张
/** * 无敌加强版上传图片 */ @RequestMapping(value="/uploadFck.action") public void uploadFck(HttpServletResponse response, HttpServletRequest request) throws Exception{ //因为上传图片是一次请求,可以使用request请求,而我们知道上传的是文件,可以强转成文件请求 MultipartRequest multipartRequest = (MultipartRequest) request; //调用方法获取多张 Map<String, MultipartFile> fileMap = multipartRequest.getFileMap(); //遍历map集合 Set<Entry<String, MultipartFile>> entrySet = fileMap.entrySet(); for (Entry<String, MultipartFile> entry : entrySet) { //根据键获取值 MultipartFile pic = entry.getValue(); //获取路径 String path = uploadService.uploadPic(pic.getBytes(), pic.getOriginalFilename(), pic.getSize()); JSONObject jo = new JSONObject(); jo.put("url", Constants.PIC_SERVER+path); jo.put("erro", 0); //乱码请求处理 response.setContentType("application/json;charset=utf-8"); //响应给前端 response.getWriter().write(jo.toString()); } } |
当上传多个图片的时候也是通过map集合遍历一个一个将内容返回给前台页面处理的4