分布式文件系统FastDFS搭建及Springboot集成demo

#### 参考资料:
1、https://www.cnblogs.com/chiangchou/p/fastdfs.html
2、https://www.aliyun.com/jiaocheng/1377274.html

 

### 一、安装FastDFS环境

 

#### 0、前言
操作环境:CentOS7 X64,以下操作都是单机环境。
我把所有的安装包下载到/usr/local/src/下,解压到当前目录。

 

#### 1、下载安装 libfastcommon
libfastcommon是从 FastDFS 和 FastDHT 中提取出来的公共 C 函数库,基础环境,安装即可 。

 

##### ① 下载libfastcommon
    wget https://github.com/happyfish100/libfastcommon/archive/V1.0.7.tar.gz

 

##### ② 解压
    tar -zxvf V1.0.7.tar.gz
    cd libfastcommon-1.0.7

 

##### ③ 编译、安装
    ./make.sh
    ./make.sh install
##### ④ libfastcommon.so 安装到了/usr/lib64/libfastcommon.so,但是FastDFS主程序设置的lib目录是/usr/local/lib,所以需要创建软链接。
    ln -s /usr/lib64/libfastcommon.so /usr/local/lib/libfastcommon.so
    ln -s /usr/lib64/libfastcommon.so /usr/lib/libfastcommon.so
    ln -s /usr/lib64/libfdfsclient.so /usr/local/lib/libfdfsclient.so
    ln -s /usr/lib64/libfdfsclient.so /usr/lib/libfdfsclient.so
#### 2、下载安装FastDFS

 

##### ① 下载FastDFS
    wget https://github.com/happyfish100/fastdfs/archive/V5.05.tar.gz

 

##### ② 解压
    tar -zxvf V5.05.tar.gz
    cd fastdfs-5.05
##### ③ 编译、安装
    ./make.sh
    ./make.sh install
##### ④ 默认安装方式安装后的相应文件与目录

 

###### A、服务脚本:
    /etc/init.d/fdfs_storaged
    /etc/init.d/fdfs_tracker
###### B、配置文件(这三个是作者给的样例配置文件) :
    /etc/fdfs/client.conf.sample
    /etc/fdfs/storage.conf.sample
    /etc/fdfs/tracker.conf.sample
###### C、命令工具在 /usr/bin/ 目录下:
    fdfs_appender_test
    fdfs_appender_test1
    fdfs_append_file
    fdfs_crc32
    fdfs_delete_file
    fdfs_download_file
    fdfs_file_info
    fdfs_monitor
    fdfs_storaged
    fdfs_test
    fdfs_test1
    fdfs_trackerd
    fdfs_upload_appender
    fdfs_upload_file
    stop.sh
    restart.sh
##### ⑤ FastDFS 服务脚本设置的 bin 目录是 /usr/local/bin, 但实际命令安装在 /usr/bin/ 下。

 

两种方式:
- 一是修改FastDFS 服务脚本中相应的命令路径,也就是把 /etc/init.d/fdfs_storaged 和 /etc/init.d/fdfs_tracker 两个脚本中的 /usr/local/bin 修改成 /usr/bin。
    vim fdfs_trackerd

 

使用查找替换命令进统一修改:%s+/usr/local/bin+/usr/bin
    vim fdfs_storaged

 

使用查找替换命令进统一修改:%s+/usr/local/bin+/usr/bin
- 二是建立 /usr/bin 到 /usr/local/bin 的软链接,我是用这种方式。

 

 

 

    ln -s /usr/bin/fdfs_trackerd   /usr/local/bin
    ln -s /usr/bin/fdfs_storaged   /usr/local/bin
    ln -s /usr/bin/stop.sh         /usr/local/bin
    ln -s /usr/bin/restart.sh      /usr/local/bin

 

#### 3、配置FastDFS跟踪器(Tracker)
配置文件详细说明参考:FastDFS 配置文件详解
##### ① 进入 /etc/fdfs,复制 FastDFS 跟踪器样例配置文件 tracker.conf.sample,并重命名为 tracker.conf。
     cd /etc/fdfs
     cp tracker.conf.sample tracker.conf
     vim tracker.conf
##### ② 编辑tracker.conf ,标红的需要修改下,其它的默认即可。
    #配置文件是否不生效,false 为生效
    disabled=false
   
    #提供服务的端口
    port=22122
   
    # Tracker 数据和日志目录地址(根目录必须存在,子目录会自动创建)
    base_path=/home/fastdfs/tracker
   
    # HTTP 服务端口
    http.server_port=6666
③ 创建tracker基础数据目录,即base_path对应的目录
    # mkdir -p /home/fastdfs/tracker
④ 防火墙中打开跟踪端口(默认的22122)
    # vim /etc/sysconfig/iptables

 

添加如下端口行:

 


    -A INPUT -m state --state NEW -m tcp -p tcp --dport 22122 -j ACCEPT

 

重启防火墙:
    # service iptables restart
⑤ 启动Tracker
初次成功启动,会在 /home/fdfsdfs/tracker/ (配置的base_path)下创建 data、logs 两个目录。
可以用这种方式启动
    # /etc/init.d/fdfs_trackerd start
也可以用这种方式启动,前提是上面创建了软链接,后面都用这种方式
    # service fdfs_trackerd start
查看 FastDFS Tracker 是否已成功启动 ,22122端口正在被监听,则算是Tracker服务安装成功。
    # netstat -unltp|grep fdfs

 

关闭Tracker命令:
    # service fdfs_trackerd stop
⑥ 设置Tracker开机启动
    # chkconfig fdfs_trackerd on
或者:
    # vim /etc/rc.d/rc.local
加入配置:

 


    /etc/init.d/fdfs_trackerd start
##### ⑦ tracker server 目录及文件结构
Tracker服务启动成功后,会在base_path下创建data、logs两个目录。目录结构如下:

 

 

 

    ${base_path}
          |__data
          |   |__storage_groups.dat:存储分组信息
          |   |__storage_servers.dat:存储服务器列表
          |__logs
          |   |__trackerd.log: tracker server 日志文件

 

#### 4、配置 FastDFS 存储 (Storage)
##### ① 进入 /etc/fdfs 目录,复制 FastDFS 存储器样例配置文件 storage.conf.sample,并重命名为 storage.conf

 


    # cd /etc/fdfs
    # cp storage.conf.sample storage.conf
    # vim storage.conf
##### ② 编辑storage.conf
标红的需要修改,其它的默认即可。

 


    # 配置文件是否不生效,false 为生效
    disabled=false
   
    # 指定此 storage server 所在 组(卷)
    group_name=group1
   
    # storage server 服务端口
    port=23000
   
    # 心跳间隔时间,单位为秒 (这里是指主动向 tracker server 发送心跳)
    heart_beat_interval=30
   
    # Storage 数据和日志目录地址(根目录必须存在,子目录会自动生成)
    base_path=/home/fastdfs/storage
   
    # 存放文件时 storage server 支持多个路径。这里配置存放文件的基路径数目,通常只配一个目录。
    store_path_count=1
   
   
    # 逐一配置 store_path_count 个路径,索引号基于 0。
    # 如果不配置 store_path0,那它就和 base_path 对应的路径一样。
    store_path0=/home/fastdfs/file
   
    # FastDFS 存储文件时,采用了两级目录。这里配置存放文件的目录个数。
    # 如果本参数只为 N(如: 256),那么 storage server 在初次运行时,会在 store_path 下自动创建 N * N 个存放文件的子目录。
    subdir_count_per_path=256
   
    # tracker_server 的列表 ,会主动连接 tracker_server
    # 有多个 tracker server 时,每个 tracker server 写一行
    tracker_server=192.168.1.141:22122
   
    # 允许系统同步的时间段 (默认是全天) 。一般用于避免高峰同步产生一些问题而设定。
    sync_start_time=00:00
    sync_end_time=23:59
    # 访问端口
    http.server_port=6666
##### ③ 创建Storage基础数据目录,对应base_path目录

 


    # mkdir -p /home/fastdfs/storage
    # 这是配置的store_path0路径
    # mkdir -p /home/fastdfs/file
④ 防火墙中打开存储器端口(默认的 23000) 

 


    # vim /etc/sysconfig/iptables
添加如下端口行:

 


    -A INPUT -m state --state NEW -m tcp -p tcp --dport 23000 -j ACCEPT

 

重启防火墙:

 


    # service iptables restart

 

##### ⑤ 启动 Storage
启动Storage前确保Tracker是启动的。初次启动成功,会在 /ljzsg/fastdfs/storage 目录下创建 data、 logs 两个目录。
可以用这种方式启动

 


    # /etc/init.d/fdfs_storaged start
也可以用这种方式,后面都用这种

 


    # service fdfs_storaged start
查看 Storage 是否成功启动,23000 端口正在被监听,就算 Storage 启动成功。

 


    # netstat -unltp|grep fdfs

 

关闭Storage命令:

 


    # service fdfs_storaged stop
查看Storage和Tracker是否在通信:
/usr/bin/fdfs_monitor /etc/fdfs/storage.conf

 

⑥ 设置 Storage 开机启动

 


    # chkconfig fdfs_storaged on
或者:

 


    # vim /etc/rc.d/rc.local
加入配置:

 


    /etc/init.d/fdfs_storaged start
##### ⑦ Storage 目录
同 Tracker,Storage 启动成功后,在base_path 下创建了data、logs目录,记录着 Storage Server 的信息。
在 store_path0 目录下,创建了N*N个子目录:

 

#### 5、文件上传测试
##### ① 修改 Tracker 服务器中的客户端配置文件 

 


    # cd /etc/fdfs
    # cp client.conf.sample client.conf
    # vim client.conf
修改如下配置即可,其它默认。

 


    # Client 的数据和日志目录base_path=/home/fastdfs/client
    # Tracker端口tracker_server=192.168.1.141:22122
##### ② 上传测试
 在linux内部执行如下命令上传 namei.jpeg 图片

 


    # /usr/bin/fdfs_upload_file /etc/fdfs/client.conf namei.jpeg
上传成功后返回文件ID号:group1/M00/00/00/wKgz6lnduTeAMdrcAAEoRmXZPp870.jpeg

 

返回的文件ID由group、存储目录、两级子目录、fileid、文件后缀名(由客户端指定,主要用于区分文件类型)拼接而成。

 

### 二、安装配置Nginx(如果已经安装过nginx,忽略前两步)
上面将文件上传成功了,但我们无法下载。因此安装Nginx作为服务器以支持Http方式访问文件。同时,后面安装FastDFS的Nginx模块也需要Nginx环境。
Nginx只需要安装到StorageServer所在的服务器即可,用于访问文件。我这里由于是单机,TrackerServer和StorageServer在一台服务器上。
#### 1、安装nginx所需环境  
##### ① gcc 安装

 


    # yum install gcc-c++
##### ② PCRE pcre-devel 安装

 


    # yum install -y pcre pcre-devel
##### ③ zlib 安装

 


    # yum install -y zlib zlib-devel
##### ④ OpenSSL 安装

 


    # yum install -y openssl openssl-devel
#### 2、安装Nginx
##### ① 下载nginx

 


    # wget -c https://nginx.org/download/nginx-1.12.1.tar.gz
##### ② 解压

 


    # tar -zxvf nginx-1.12.1.tar.gz
    # cd nginx-1.12.1
##### ③ 使用默认配置

 


    # ./configure
##### ④ 编译、安装

 


    # make
    # make install
##### ⑤ 启动nginx

 


    # cd /usr/local/nginx/sbin/
    # ./nginx

 

其它命令

 


    # ./nginx -s stop
    # ./nginx -s quit
    # ./nginx -s reload
##### ⑥ 设置开机启动

 


    # vim /etc/rc.local

 

添加一行:

 


    /usr/local/nginx/sbin/nginx

 

设置执行权限

 


    # chmod 755 rc.local
##### ⑦ 查看nginx的版本及模块

 


    /usr/local/nginx/sbin/nginx -V

 

##### ⑧ 防火墙中打开Nginx端口(默认的 80) 
添加后就能在本机使用80端口访问了。

 


    # vim /etc/sysconfig/iptables

 

添加如下端口行:

 


    -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

 

重启防火墙:

 


    # service iptables restart

 

#### 3、访问文件
简单的测试访问文件
##### ① 修改nginx.conf

 


    # vim /usr/local/nginx/conf/nginx.conf

 

添加如下行,将 /group1/M00 映射到 /ljzsg/fastdfs/file/data

 


    location /group1/M00 {
        alias /ljzsg/fastdfs/file/data;
    }

 

重启nginx

 


    # /usr/local/nginx/sbin/nginx -s reload

 

##### ② 在浏览器访问之前上传的图片、成功。
http://192.168.1.141/group1/M00/00/00/wKgz6lnduTeAMdrcAAEoRmXZPp870.jpeg
### 三、FastDFS安装nginx模块
#### 1、安装配置Nginx模块
###### ① fastdfs-nginx-module 模块说明
  FastDFS 通过 Tracker 服务器,将文件放在 Storage 服务器存储, 但是同组存储服务器之间需要进行文件复制, 有同步延迟的问题。
  假设 Tracker 服务器将文件上传到了 192.168.1.141,上传成功后文件 ID已经返回给客户端。
  此时 FastDFS 存储集群机制会将这个文件同步到同组存储 192.168.1.142,在文件还没有复制完成的情况下,客户端如果用这个文件 ID 在 192.168.1.142上取文件,就会出现文件无法访问的错误。
  而 fastdfs-nginx-module 可以重定向文件链接到源服务器取文件,避免客户端由于复制延迟导致的文件无法访问错误。
###### ② 下载 fastdfs-nginx-module、解压

 


    # 这里为啥这么长一串呢,因为最新版的master与当前nginx有些版本问题。
    # wget https://github.com/happyfish100/fastdfs-nginx-module/archive/5e5f3566bbfa57418b5506aaefbe107a42c9fcb1.zip
   
    # 解压
    # unzip 5e5f3566bbfa57418b5506aaefbe107a42c9fcb1.zip
   
    # 重命名
    # mv fastdfs-nginx-module-5e5f3566bbfa57418b5506aaefbe107a42c9fcb1  fastdfs-nginx-module-master
###### ③ 配置Nginx
在nginx中添加模块
先停掉nginx服务

 


    # /usr/local/nginx/sbin/ngix -s stop

 

进入解压包目录

 


    # cd /usr/local/src/nginx-1.12.1/

 

添加模块

 


    # ./configure --add-module=../fastdfs-nginx-module-master/src

 

重新编译、安装

 


    # make && make install
 ④ 查看Nginx的模块

 


    # /usr/local/nginx/sbin/nginx -V
有下面这个就说明添加模块成功

 

###### ⑤ 复制 fastdfs-nginx-module 源码中的配置文件到/etc/fdfs 目录, 并修改

 


    # cd /usr/local/src/fastdfs-nginx-module-master/src
   
    # cp mod_fastdfs.conf /etc/fdfs/
修改如下配置,其它默认

 


    # 连接超时时间
    connect_timeout=10
   
    # Tracker Server
    tracker_server=192.168.1.141:22122
   
    # StorageServer 默认端口
    storage_server_port=23000
   
    # 如果文件ID的uri中包含/group**,则要设置为true
    url_have_group_name = true
   
    # Storage 配置的store_path0路径,必须和storage.conf中的一致
    store_path0=/home/fastdfs/file
###### ⑥ 复制 FastDFS 的部分配置文件到/etc/fdfs 目录

 


    # cd /usr/local/src/fastdfs-5.05/conf/
    # cp anti-steal.jpg http.conf mime.types /etc/fdfs/
######  ⑦ 配置nginx,修改nginx.conf

 


    # vim /usr/local/nginx/conf/nginx.conf
修改配置,其它的默认
在80端口下添加fastdfs-nginx模块

 


    location ~/group([0-9])/M00 {
        ngx_fastdfs_module;
    }

 

注意:
  listen 80 端口值是要与 /etc/fdfs/storage.conf 中的 http.server_port=80 (前面改成80了)相对应。如果改成其它端口,则需要统一,同时在防火墙中打开该端口。
  location 的配置,如果有多个group则配置location ~/group([0-9])/M00 ,没有则不用配group。
###### ⑧ 在/home/fastdfs/file 文件存储目录下创建软连接,将其链接到实际存放数据的目录,这一步可以省略。

 


    # ln -s /home/fastdfs/file/data/ /home/fastdfs/file/data/M00
###### ⑨ 启动nginx

 


    # /usr/local/nginx/sbin/nginx
打印处如下就算配置成功

 

###### ⑩ 在地址栏访问。
能下载文件就算安装成功。注意和第三点中直接使用nginx路由访问不同的是,这里配置 fastdfs-nginx-module 模块,可以重定向文件链接到源服务器取文件。
http://192.168.1.141/group1/M00/00/00/wKgz6lnduTeAMdrcAAEoRmXZPp870.jpeg
###  四、缩略图支持image_filter
####  1 http_image_filter_module
http_image_filter_module是nginx提供的集成图片处理模块,支持nginx-0.7.54以后的版本,在网站访问量不是很高磁盘有限不想生成多余的图片文件的前提下可,就可以用它实时缩放图片,旋转图片,验证图片有效性以及获取图片宽高以及图片类型信息。
###### 1.1 查看有没有安装

 


    # /usr/local/nginx/sbin/nginx -V 

 

    nginx version: nginx/1.5.0
    built by gcc 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC) 
    TLS SNI support enabled
    configure arguments: --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_realip_module --add-module=/usr/local/src/nginx/fastdfs-nginx-module/src

 

##### 2 模块说明

 


    image_filter off;
    #关闭模块
   
    image_filter test;
    #确保图片是jpeg gif png否则返415错误
   
    image_filter size;
    #输出有关图像的json格式:例如以下显示{ "img" : { "width": 100, "height": 100, "type": "gif" } } 出错显示:{}
   
    image_filter rotate 90|180|270;
    #旋转指定度数的图像,參数能够包括变量,单独或一起与resize crop一起使用。
   
    image_filter resize width height;
    #按比例降低图像到指定大小,公降低一个能够还有一个用"-"来表示,出错415,參数值可包括变量,能够与rotate一起使用,则两个一起生效。
    image_filter crop width height;
    #按比例降低图像比較大的側面积和还有一側多余的载翦边缘,其他和rotate一样。没太理解
   
    image_filter_buffer 10M;
    #设置读取图像缓冲的最大大小,超过则415错误。
   
    image_filter_interlace on;
    #假设启用,终于的图像将被交错。对于JPEG,终于的图像将在“渐进式JPEG”格式。
   
    image_filter_jpeg_quality 95;
    #设置变换的JPEG图像的期望质量。可接受的值是从1到100的范围内。较小的值通常意味着既降低图像质量,降低数据传输,推荐的最大值为95。參数值能够包括变量。
   
    image_filter_sharpen 100;
    #添加了终于图像的清晰度。锐度百分比能够超过100。零值将禁用锐化。參数值能够包括变量。
   
    image_filter_transparency on;
    #定义是否应该透明转换的GIF图像或PNG图像与调色板中指定的颜色时,能够保留。透明度的损失将导致更好的图像质量。在PNG的Alpha通道总是保留透明度。

 

##### 3 安装
###### 3.1 安装gd,HttpImageFilterModule模块需要依赖gd-devel的支持

 


    # yum -y install gd-devel
###### 3.2 将http_image_filter_module包含进来

 


    # cd /usr/local/src/nginx
    # ./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_realip_module --add-module=/usr/local/src/fastdfs/fastdfs-nginx-module/src --with-http_image_filter_module
    #  make && make install

 

#### 4、 配置nginx

 

   

 

    location ~ group1/M00/(.+)_([0-9]+)x([0-9]+)\.(jpg|gif|png) {
     alias /home/fastdfs/file/data;
     ngx_fastdfs_module;
     set $w $2;
     set $h $3;          
   
     if ($w != "0") {
      rewrite group1/M00(.+)_(\d+)x(\d+)\.(jpg|gif|png)$ group1/M00$1.$4 break;
     }
   
     if ($h != "0") {
      rewrite group1/M00(.+)_(\d+)x(\d+)\.(jpg|gif|png)$ group1/M00$1.$4 break;
     }
   
     #根据给定的长宽生成缩略图  
     image_filter resize $w $h;
   
     #原图最大2M,要裁剪的图片超过2M返回415错误,需要调节参数image_filter_buffer 
     image_filter_buffer 2M;
   
     #try_files group1/M00$1.$4 $1.jpg;
     }
   
   
     location ~ group1/M00/(.+)\.?(.+){
      alias /home/fastdfs/file/data;
      ngx_fastdfs_module;
     }
    }

 

### 五、Springboot集成
#### 加入依赖:
```xml

 com.github.tobato
 fastdfs-client
 1.26.4

```

 

#### yml配置:
    fdfs:
        so-timeout: 1500 #socketsocket连接超时时长
        connect-timeout: 600 #连接tracker服务器超时时长
        thumb-image: #缩略图生成参数,可选
            width: 150
            height: 150
        tracker-list: #TrackerList参数,支持多个,我这里只有一个,如果有多个在下方加- x.x.x.x:port
          - 192.168.1.141:22122
        imgHost: http://192.168.1.141  #图片访问路径前缀

 


#### 增加配置类(此类里面什么都不需要做,也可以把@Import和@EnableMBeanExport放在启动类上,感觉启动类上放太多东西不好看就增加了一个配置类)
FdfsConfiguration.java

 

    package com.qfkj.upload.config;
       
    import com.github.tobato.fastdfs.FdfsClientConfig;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.EnableMBeanExport;
    import org.springframework.context.annotation.Import;
    import org.springframework.jmx.support.RegistrationPolicy;
   
    @Configuration
    @Import(FdfsClientConfig.class)//注解,就可以拥有带有连接池的FastDFS Java客户端了
    @EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
    public class FdfsConfiguration {
   
    }

 

#### 上传工具类封装
FastDFSUploadUtils.java

 

 

 

    package com.qfkj.upload.utils;
   
    import com.github.tobato.fastdfs.domain.StorePath;
    import com.github.tobato.fastdfs.domain.ThumbImageConfig;
    import com.github.tobato.fastdfs.proto.storage.DownloadByteArray;
    import com.github.tobato.fastdfs.service.FastFileStorageClient;
    import com.qfkj.upload.config.FdfsConfig;
    import org.apache.commons.io.FilenameUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    import org.springframework.web.multipart.MultipartFile;
   
    import java.io.IOException;
    import java.io.InputStream;
   
    /**
     * @author 韩国红
     * create 2018-11-22
     */
    @Component
    public class FastDFSUploadUtils {
        @Autowired
        private FastFileStorageClient storageClient;
   
        @Autowired
        private ThumbImageConfig thumbImageConfig;
   
        @Value("${fdfs.imgHost}")
        private String imgHost;
   
        /**
         * 上传并返回全访问路径
         * @param file
         * @return
         * @throws IOException
         */
        public String uploadFile(MultipartFile file) throws IOException {
            //StorePath storePath = storageClient.uploadFile((InputStream)file.getInputStream(),file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()),null);
            StorePath storePath = storageClient.uploadImageAndCrtThumbImage((InputStream)file.getInputStream(),file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()),null);
            System.out.println(imgHost + "/" + thumbImageConfig.getThumbImagePath(storePath.getFullPath()));
            return getResAccessUrl(storePath);
        }
   
        /**
         * 上传并返回半截存储路径
         * @param file
         * @return
         * @throws IOException
         */
        public String uploadFile_HalfPath(MultipartFile file) throws IOException {
            StorePath storePath = storageClient.uploadFile((InputStream)file.getInputStream(),file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()),null);
            return storePath.getFullPath();
        }
   
        /**
         * 根据半截路径获取可访问的全路径
         * @param filePath
         * @return
         */
        public String getResAccessUrl(String filePath){
            String fileUrl = imgHost + "/" + filePath;
            return fileUrl;
        }
   
        /**
         * 删除
         * @param fileUrl
         */
        public void deleteFile(String fileUrl){
            StorePath storePath = StorePath.praseFromUrl(fileUrl);
            storageClient.deleteFile(storePath.getGroup(),storePath.getPath());
        }
   
        /**
         * 下载
         * @param fileUrl
         * @return
         * @throws IOException
         */
        public byte[] downloadFile(String fileUrl) throws IOException {
            StorePath storePath = StorePath.praseFromUrl(fileUrl);
            String group = storePath.getGroup();
            String path = storePath.getPath();
            DownloadByteArray downloadByteArray = new DownloadByteArray();
            byte[] bytes = storageClient.downloadFile(group, path, downloadByteArray);
            return bytes;
        }
   
        /**
         * 封装文件完整URL地址
         * @param storePath
         * @return
         */
        private String getResAccessUrl(StorePath storePath) {
            String fileUrl = imgHost + "/" + storePath.getFullPath();
            return fileUrl;
        }
   
        public String getImgHost() {
            return imgHost;
        }
   
        public void setImgHost(String imgHost) {
            this.imgHost = imgHost;
        }
    }
   

 


#### 上传、下载、删除示例:
TestController.java

    package com.qfkj.upload.modules.controller;
   
    import com.qfkj.upload.utils.FastDFSUploadUtils;
    import com.qfkj.upload.utils.R;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.multipart.MultipartFile;
   
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.net.URLEncoder;
   
    @Api("测试")
    @RestController
    public class TestController {
   
        @Autowired
        private FastDFSUploadUtils fastDFSClientUtils;
   
        @ApiOperation(value = "测试上传",notes = "测试上传")
        @PostMapping("/fdfs_upload")
        public R fdfsUpload(@RequestParam("file") MultipartFile file) {
            if (file.isEmpty()) {
                return R.fail("请选择文件");
            }
   
            try {
                String fileUrl= fastDFSClientUtils.uploadFile(file);
                return R.ok((Object)fileUrl);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return R.error();
        }
   
        @ApiOperation(value = "删除文件",notes = "删除文件")
        @PostMapping("/fdfs_delete")
        public R delete(@RequestParam("fileUrl") String fileUrl) {
           try {
               fastDFSClientUtils.deleteFile(fileUrl);
           }catch (Exception e){
               e.printStackTrace();
               return R.error(e.toString());
           }
            return R.ok();
        }
   
        @ApiOperation(value = "下载文件",notes = "下载文件")
        @GetMapping("/fdfs_download")
        public void download(@RequestParam("fileUrl") String fileUrl, HttpServletResponse response) throws IOException {
            byte[] bytes = fastDFSClientUtils.downloadFile(fileUrl);
            // 这里只是为了整合fastdfs,所以写死了文件格式。需要在上传的时候保存文件名。下载的时候使用对应的格式
            response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("sb.jpg", "UTF-8"));
            response.setCharacterEncoding("UTF-8");
            ServletOutputStream outputStream = null;
            try {
                outputStream = response.getOutputStream();
                outputStream.write(bytes);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    outputStream.flush();
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
   

你可能感兴趣的:(分布式文件系统)