FastDFS快速实现和SpringBoot的整合开发

FastDFS快速实现和SpringBoot的整合开发
在这里插入图片描述

FastDFS客户端操作

1.Fastdfs-Java-client

  首先我们来看下如何实现FastDFS中提供的JavaAPI来直接实现对应的文件上传和下载操作。

1.1 文件上传

  先来看下文件上传的流程

FastDFS快速实现和SpringBoot的整合开发
image.png

  上传流程的文字梳理为:

  1. 客户端访问Tracker

  2. Tracker 返回Storage的ip和端口

  3. 客户端直接访问Storage,把文件内容和元数据发送过去。

  4. Storage返回文件存储id。包含了组名和文件名

  首先创建一个普通的maven项目,然后引入对应的依赖

 1<dependencies>
2    <dependency>
3        <groupId>cn.bestwu</groupId>
4        <artifactId>fastdfs-client-java</artifactId>
5        <version>1.27</version>
6    </dependency>
7    <dependency>
8        <groupId>org.apache.commons</groupId>
9        <artifactId>commons-lang3</artifactId>
10        <version>3.4</version>
11    </dependency>
12</dependencies>

  然后编写FastDFS的配置文件,内容如下:注意ip修改为你自己对应的ip即可

1connect_timeout = 10
2network_timeout = 30
3charset = UTF-8
4http.tracker_http_port = 8080
5tracker_server = 192.168.56.100:22122
FastDFS快速实现和SpringBoot的整合开发
image.png

  然后导入对应的工具类,在工具类中完成了StorageClient的实例化,并提供了相关的上传和下载的方法。

  1package com.bobo.fastdfs.config;
2
3import org.apache.commons.lang3.StringUtils;
4import org.csource.common.NameValuePair;
5import org.csource.fastdfs.*;
6
7import java.io.*;
8
9public class FastDFSClient {
10    private static final String CONF_FILENAME = Thread.currentThread().getContextClassLoader().getResource("").getPath() + "fdfs_client.conf";
11
12    private static StorageClient storageClient = null;
13
14    /**
15     * 只加载一次.
16     */

17    static {
18        try {
19            ClientGlobal.init(CONF_FILENAME);
20            TrackerClient trackerClient = new TrackerClient(ClientGlobal.g_tracker_group);
21            TrackerServer trackerServer = trackerClient.getConnection();
22            StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);
23            storageClient = new StorageClient(trackerServer, storageServer);
24        } catch (Exception e) {
25            e.printStackTrace();
26        }
27    }
28
29    /**
30     *
31     * @param inputStream
32     *    上传的文件输入流
33     * @param fileName
34     *    上传的文件原始名
35     * @return
36     */

37    public static String[] uploadFile(InputStream inputStream, String fileName) {
38        try {
39            // 文件的元数据
40            NameValuePair[] meta_list = new NameValuePair[2];
41            // 第一组元数据,文件的原始名称
42            meta_list[0] = new NameValuePair("file name", fileName);
43            // 第二组元数据
44            meta_list[1] = new NameValuePair("file length", inputStream.available()+"");
45            // 准备字节数组
46            byte[] file_buff = null;
47            if (inputStream != null) {
48                // 查看文件的长度
49                int len = inputStream.available();
50                // 创建对应长度的字节数组
51                file_buff = new byte[len];
52                // 将输入流中的字节内容,读到字节数组中。
53                inputStream.read(file_buff);
54            }
55            // 上传文件。参数含义:要上传的文件的内容(使用字节数组传递),上传的文件的类型(扩展名),元数据
56            String[] fileids = storageClient.upload_file(file_buff, getFileExt(fileName), meta_list);
57            return fileids;
58        } catch (Exception ex) {
59            ex.printStackTrace();
60            return null;
61        }
62    }
63
64    /**
65     *
66     * @param file
67     *            文件
68     * @param fileName
69     *            文件名
70     * @return 返回Null则为失败
71     */

72    public static String[] uploadFile(File file, String fileName) {
73        FileInputStream fis = null;
74        try {
75            NameValuePair[] meta_list = null// new NameValuePair[0];
76            fis = new FileInputStream(file);
77            byte[] file_buff = null;
78            if (fis != null) {
79                int len = fis.available();
80                file_buff = new byte[len];
81                fis.read(file_buff);
82            }
83
84            String[] fileids = storageClient.upload_file(file_buff, getFileExt(fileName), meta_list);
85            return fileids;
86        } catch (Exception ex) {
87            return null;
88        }finally{
89            if (fis != null){
90                try {
91                    fis.close();
92                } catch (IOException e) {
93                    e.printStackTrace();
94                }
95            }
96        }
97    }
98
99    /**
100     * 根据组名和远程文件名来删除一个文件
101     *
102     * @param groupName
103     *            例如 "group1" 如果不指定该值,默认为group1
104     * @param remoteFileName
105     *            例如"M00/00/00/wKgxgk5HbLvfP86RAAAAChd9X1Y736.jpg"
106     * @return 0为成功,非0为失败,具体为错误代码
107     */

108    public static int deleteFile(String groupName, String remoteFileName) {
109        try {
110            int result = storageClient.delete_file(groupName == null ? "group1" : groupName, remoteFileName);
111            return result;
112        } catch (Exception ex) {
113            return 0;
114        }
115    }
116
117    /**
118     * 修改一个已经存在的文件
119     *
120     * @param oldGroupName
121     *            旧的组名
122     * @param oldFileName
123     *            旧的文件名
124     * @param file
125     *            新文件
126     * @param fileName
127     *            新文件名
128     * @return 返回空则为失败
129     */

130    public static String[] modifyFile(String oldGroupName, String oldFileName, File file, String fileName) {
131        String[] fileids = null;
132        try {
133            // 先上传
134            fileids = uploadFile(file, fileName);
135            if (fileids == null) {
136                return null;
137            }
138            // 再删除
139            int delResult = deleteFile(oldGroupName, oldFileName);
140            if (delResult != 0) {
141                return null;
142            }
143        } catch (Exception ex) {
144            return null;
145        }
146        return fileids;
147    }
148
149    /**
150     * 文件下载
151     *
152     * @param groupName 卷名
153     * @param remoteFileName 文件名
154     * @return 返回一个流
155     */

156    public static InputStream downloadFile(String groupName, String remoteFileName) {
157        try {
158            byte[] bytes = storageClient.download_file(groupName, remoteFileName);
159            InputStream inputStream = new ByteArrayInputStream(bytes);
160            return inputStream;
161        } catch (Exception ex) {
162            return null;
163        }
164    }
165
166    public static NameValuePair[] getMetaDate(String groupName, String remoteFileName){
167        try{
168            NameValuePair[] nvp = storageClient.get_metadata(groupName, remoteFileName);
169            return nvp;
170        }catch(Exception ex){
171            ex.printStackTrace();
172            return null;
173        }
174    }
175
176    /**
177     * 获取文件后缀名(不带点).
178     *
179     * @return 如:"jpg" or "".
180     */

181    private static String getFileExt(String fileName) {
182        if (StringUtils.isBlank(fileName) || !fileName.contains(".")) {
183            return "";
184        } else {
185            return fileName.substring(fileName.lastIndexOf(".") + 1); // 不带最后的点
186        }
187    }
188
189}

  然后我们就可以来测试上传的操作了。

 1    public static void main(String[] args) {
2        try {
3            File file = new File("D:/2.jpg");
4            InputStream is = new FileInputStream(file);
5            String fileName = UUID.randomUUID().toString()+".jpg";
6            String[] result = FastDFSClient.uploadFile(is, fileName);
7            System.out.println(Arrays.toString(result));
8        } catch (Exception e) {
9            e.printStackTrace();
10        }
11    }
FastDFS快速实现和SpringBoot的整合开发
image.png

访问即可:http://192.168.56.100:8888/group1/M00/00/00/wKg4ZGHcUE6AZA2UAAW8dIX5p50374.jpg

  返回后的字符串的结构说明

FastDFS快速实现和SpringBoot的整合开发
image.png

1.2 文件下载

  文件下载的流程,如下

FastDFS快速实现和SpringBoot的整合开发
image.png

  文件下载的流程为:

  1. client询问tracker需要下载的文件的storage,参数为文件的标识(group加文件名)。

  2. tracker根据客户端的参数返回一台可用的storage。

  3. client根据返回的storage直接完成对应的文件的下载。

  有了上面的基础,文件下载就非常简单了,我们只需要根据前面上传的文件的group和文件的存储路径就可以通过StorageClient中提供的downloadFile方法把对应的文件下载下来了,具体的代码如下

 1    /**
2     * 文件下载
3     */

4    public static void downloadFile(){
5        try {
6            InputStream is = FastDFSClient
7                    .downloadFile("group1""M00/00/00/wKg4ZGHcUE6AZA2UAAW8dIX5p50374.jpg");
8            OutputStream os = new FileOutputStream(new File("D:/12.jpg"));
9            int index = 0 ;
10            while((index = is.read())!=-1){
11                os.write(index);
12            }
13            os.flush();
14            os.close();
15            is.close();
16        } catch (Exception e) {
17            e.printStackTrace();
18        }
19    }

2.SpringBoot整合

  我们在实际工作中基本都是和SpringBoot整合在一起来使用的,那么我们就来看看FastDFS是如何在SpringBoot项目中来使用的。首先创建一个普通的SpringBoot项目,然后导入fastdfs-spring-boot-starter这个依赖。

 1    <dependencies>
2        <dependency>
3            <groupId>org.springframework.boot</groupId>
4            <artifactId>spring-boot-starter-web</artifactId>
5        </dependency>
6
7        <dependency>
8            <groupId>org.springframework.boot</groupId>
9            <artifactId>spring-boot-starter-test</artifactId>
10            <scope>test</scope>
11        </dependency>
12
13        <dependency>
14            <groupId>com.luhuiguo</groupId>
15            <artifactId>fastdfs-spring-boot-starter</artifactId>
16            <version>0.2.0</version>
17        </dependency>
18    </dependencies>

  既然是一个starter,那么必然会在spring.factories文件中提供对应的自动配置类。

FastDFS快速实现和SpringBoot的整合开发
image.png

  可以看到给我们提供的配置类为FdfsAutoConfiguration进入后可以看到帮我们注入了很多的核心对象。

FastDFS快速实现和SpringBoot的整合开发
image.png

  然后可以看到系统提供的配置信息,前缀为 fdfs

FastDFS快速实现和SpringBoot的整合开发
image.png

  然后我们就可以在application.properties中配置FastDFS的配置信息了。

FastDFS快速实现和SpringBoot的整合开发
image.png

  配置完成后我们就可以测试文件的上传下载操作了

 1@SpringBootTest
2class FastDfsSpringBootApplicationTests {
3
4    @Autowired
5    public FastFileStorageClient storageClient;
6
7
8    @Test
9    void contextLoads() throws Exception{
10        File file = new File("d:\2.jpg");
11        StorePath path = storageClient.uploadFile(null,new FileInputStream(file),file.length(),file.getName());
12        System.out.println(path.getFullPath());
13    }
14
15}

文件操作成功

FastDFS快速实现和SpringBoot的整合开发
image.png


原文始发于微信公众号(波哥带你学编程):FastDFS快速实现和SpringBoot的整合开发

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/59210.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!