FastDFS快速实现和SpringBoot的整合开发
FastDFS客户端操作
1.Fastdfs-java-client
首先我们来看下如何实现FastDFS中提供的JavaAPI来直接实现对应的文件上传和下载操作。
1.1 文件上传
先来看下文件上传的流程
上传流程的文字梳理为:
- 客户端访问Tracker
- Tracker 返回Storage的ip和端口
- 客户端直接访问Storage,把文件内容和元数据发送过去。
- Storage返回文件存储id。包含了组名和文件名
首先创建一个普通的maven项目,然后引入对应的依赖
<dependencies>
<dependency>
<groupId>cn.bestwu</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
</dependencies>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
然后编写FastDFS的配置文件,内容如下:注意ip修改为你自己对应的ip即可
connect_timeout = 10
network_timeout = 30
charset = UTF-8
http.tracker_http_port = 8080
tracker_server = 192.168.56.100:22122
- 1
- 2
- 3
- 4
- 5
然后导入对应的工具类,在工具类中完成了StorageClient的实例化,并提供了相关的上传和下载的方法。
package com.bobo.fastdfs.config;
import org.apache.commons.lang3.StringUtils;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import java.io.*;
public class FastDFSClient {
private static final String CONF_FILENAME = Thread.currentThread().getContextClassLoader().getResource("").getPath() + "fdfs_client.conf";
private static StorageClient storageClient = null;
/**
* 只加载一次.
*/
static {
try {
ClientGlobal.init(CONF_FILENAME);
TrackerClient trackerClient = new TrackerClient(ClientGlobal.g_tracker_group);
TrackerServer trackerServer = trackerClient.getConnection();
StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);
storageClient = new StorageClient(trackerServer, storageServer);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*
* @param inputStream
* 上传的文件输入流
* @param fileName
* 上传的文件原始名
* @return
*/
public static String[] uploadFile(InputStream inputStream, String fileName) {
try {
// 文件的元数据
NameValuePair[] meta_list = new NameValuePair[2];
// 第一组元数据,文件的原始名称
meta_list[0] = new NameValuePair("file name", fileName);
// 第二组元数据
meta_list[1] = new NameValuePair("file length", inputStream.available()+"");
// 准备字节数组
byte[] file_buff = null;
if (inputStream != null) {
// 查看文件的长度
int len = inputStream.available();
// 创建对应长度的字节数组
file_buff = new byte[len];
// 将输入流中的字节内容,读到字节数组中。
inputStream.read(file_buff);
}
// 上传文件。参数含义:要上传的文件的内容(使用字节数组传递),上传的文件的类型(扩展名),元数据
String[] fileids = storageClient.upload_file(file_buff, getFileExt(fileName), meta_list);
return fileids;
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
/**
*
* @param file
* 文件
* @param fileName
* 文件名
* @return 返回Null则为失败
*/
public static String[] uploadFile(File file, String fileName) {
FileInputStream fis = null;
try {
NameValuePair[] meta_list = null; // new NameValuePair[0];
fis = new FileInputStream(file);
byte[] file_buff = null;
if (fis != null) {
int len = fis.available();
file_buff = new byte[len];
fis.read(file_buff);
}
String[] fileids = storageClient.upload_file(file_buff, getFileExt(fileName), meta_list);
return fileids;
} catch (Exception ex) {
return null;
}finally{
if (fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 根据组名和远程文件名来删除一个文件
*
* @param groupName
* 例如 "group1" 如果不指定该值,默认为group1
* @param remoteFileName
* 例如"M00/00/00/wKgxgk5HbLvfP86RAAAAChd9X1Y736.jpg"
* @return 0为成功,非0为失败,具体为错误代码
*/
public static int deleteFile(String groupName, String remoteFileName) {
try {
int result = storageClient.delete_file(groupName == null ? "group1" : groupName, remoteFileName);
return result;
} catch (Exception ex) {
return 0;
}
}
/**
* 修改一个已经存在的文件
*
* @param oldGroupName
* 旧的组名
* @param oldFileName
* 旧的文件名
* @param file
* 新文件
* @param fileName
* 新文件名
* @return 返回空则为失败
*/
public static String[] modifyFile(String oldGroupName, String oldFileName, File file, String fileName) {
String[] fileids = null;
try {
// 先上传
fileids = uploadFile(file, fileName);
if (fileids == null) {
return null;
}
// 再删除
int delResult = deleteFile(oldGroupName, oldFileName);
if (delResult != 0) {
return null;
}
} catch (Exception ex) {
return null;
}
return fileids;
}
/**
* 文件下载
*
* @param groupName 卷名
* @param remoteFileName 文件名
* @return 返回一个流
*/
public static InputStream downloadFile(String groupName, String remoteFileName) {
try {
byte[] bytes = storageClient.download_file(groupName, remoteFileName);
InputStream inputStream = new ByteArrayInputStream(bytes);
return inputStream;
} catch (Exception ex) {
return null;
}
}
public static NameValuePair[] getMetaDate(String groupName, String remoteFileName){
try{
NameValuePair[] nvp = storageClient.get_metadata(groupName, remoteFileName);
return nvp;
}catch(Exception ex){
ex.printStackTrace();
return null;
}
}
/**
* 获取文件后缀名(不带点).
*
* @return 如:"jpg" or "".
*/
private static String getFileExt(String fileName) {
if (StringUtils.isBlank(fileName) || !fileName.contains(".")) {
return "";
} else {
return fileName.substring(fileName.lastIndexOf(".") + 1); // 不带最后的点
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
然后我们就可以来测试上传的操作了。
public static void main(String[] args) {
try {
File file = new File("D:/2.jpg");
InputStream is = new FileInputStream(file);
String fileName = UUID.randomUUID().toString()+".jpg";
String[] result = FastDFSClient.uploadFile(is, fileName);
System.out.println(Arrays.toString(result));
} catch (Exception e) {
e.printStackTrace();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
访问即可:http://192.168.56.100:8888/group1/M00/00/00/wKg4ZGHcUE6AZA2UAAW8dIX5p50374.jpg
返回后的字符串的结构说明
1.2 文件下载
文件下载的流程,如下
文件下载的流程为:
- client询问tracker需要下载的文件的storage,参数为文件的标识(group加文件名)。
- tracker根据客户端的参数返回一台可用的storage。
- client根据返回的storage直接完成对应的文件的下载。
有了上面的基础,文件下载就非常简单了,我们只需要根据前面上传的文件的group和文件的存储路径就可以通过StorageClient中提供的downloadFile方法把对应的文件下载下来了,具体的代码如下
/**
* 文件下载
*/
public static void downloadFile(){
try {
InputStream is = FastDFSClient
.downloadFile("group1", "M00/00/00/wKg4ZGHcUE6AZA2UAAW8dIX5p50374.jpg");
OutputStream os = new FileOutputStream(new File("D:/12.jpg"));
int index = 0 ;
while((index = is.read())!=-1){
os.write(index);
}
os.flush();
os.close();
is.close();
} catch (Exception e) {
e.printStackTrace();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
2.SpringBoot整合
我们在实际工作中基本都是和SpringBoot整合在一起来使用的,那么我们就来看看FastDFS是如何在SpringBoot项目中来使用的。首先创建一个普通的SpringBoot项目,然后导入fastdfs-spring-boot-starter这个依赖。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.luhuiguo</groupId>
<artifactId>fastdfs-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
</dependencies>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
既然是一个starter,那么必然会在spring.factories文件中提供对应的自动配置类。
可以看到给我们提供的配置类为FdfsAutoConfiguration进入后可以看到帮我们注入了很多的核心对象。
然后可以看到系统提供的配置信息,前缀为 fdfs
然后我们就可以在application.properties中配置FastDFS的配置信息了。
配置完成后我们就可以测试文件的上传下载操作了
@SpringBootTest
class FastDfsSpringBootApplicationTests {
@Autowired
public FastFileStorageClient storageClient;
@Test
void contextLoads() throws Exception{
File file = new File("d:\\2.jpg");
StorePath path = storageClient.uploadFile(null,new FileInputStream(file),file.length(),file.getName());
System.out.println(path.getFullPath());
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
文件操作成功
文章来源: dpb-bobokaoya-sm.blog.csdn.net,作者:波波烤鸭,版权归原作者所有,如需转载,请联系作者。
原文链接:dpb-bobokaoya-sm.blog.csdn.net/article/details/122441905
- 点赞
- 收藏
- 关注作者
评论(0)