基础原理
来源
https://segmentfault.com/a/1190000038786876
什么是FastDFS
fastDFS 是以C语言开发的一项开源轻量级分布式文件系统,他对文件进行管理,主要功能有:文件存储,文件同步,文件访问(文件上传/下载),特别适合以文件为载体的在线服务,如图片网站,视频网站等
系统架构
FastDFS服务端有两个角色:跟踪器(tracker)和存储节点(storage)。跟踪器主要做调度工作,在访问上起负载均衡的作用。
存储节点存储文件,完成文件管理的所有功能:存储、同步和提供存取接口,FastDFS同时对文件的meta data进行管理。所谓文件的meta data就是文件的相关属性,以键值对(key value pair)方式表示,如:width=1024,其中的key为width,value为1024。文件meta dat是文件属性列表,可以包含多个键值对。
依赖下载
因为fastdfs-client-java-1.27-SNAPSHOT.jar这个依赖包在maven中央仓库是没有的。
需要自己编译源码成jar本地安装到maven 的本地仓库,安装完以后就能正常引用了(注意:本地必须安装了Maven,并配置好Maven环境变量)
官网
https://github.com/happyfish100/fastdfs-client-java
来源:
分享知识-快乐自己:解决 Maven 无法下载 fastdfs-client-java 依赖。 - GDBD - 博客园
额外依赖
<!-- commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<!-- log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
配置文件
config.properties
connect_timeout = 10 network_timeout = 30 charset = UTF-8 http.tracker_http_port = 8080 http.anti_steal_token = no fastdfs.tracker_servers = 192.168.10.183:22122 #web展示的uri fastdfs.web.uri=http://192.168.10.183:80
工具类
来源:
FastDFS分布文件系统Java客户端使用_技术改变生活-CSDN博客_fastdfs 客户端
package com.wg.utils;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
/**
* @description: FastDFS工具类
* @author: dayibalang
* @time: 2020/7/22 9:18
*/
public class FastDFSUtil {
private static final Logger logger = Logger.getLogger(FastDFSUtil.class);
private static final String CONF_FILENAME = "fdfs_client.conf";
private static String fdfs_web_uri=null;
static {
try {
Properties properties = new Properties();
properties.load(new FileInputStream(new File("./conf/"+CONF_FILENAME)));
fdfs_web_uri=properties.getProperty("fastdfs.web.uri");
ClientGlobal.initByProperties(properties);
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
}
}
private static StorageClient1 getStorageClient1(){
try {
TrackerClient trackerClient = new TrackerClient(ClientGlobal.g_tracker_group);
TrackerServer trackerServer = trackerClient.getTrackerServer();
StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);
return new StorageClient1(trackerServer, storageServer);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static class Singleton{
private static StorageClient1 storageClient1=getStorageClient1();
}
/**
* 功能描述:文件上传 返回 fileId
* @author dayibalang
* @date 2020/7/22
* @param file
* @return java.lang.String
*/
public static String uploadFile(File file, Map<String,String> metaList) {
FileInputStream fis = null;
String fileId = null;
try {
NameValuePair[] meta_list = null;
NameValuePair[] nameValuePairs = null;
if (metaList != null) {
nameValuePairs = new NameValuePair[metaList.size()];
int index = 0;
for (Iterator<Map.Entry<String,String>> iterator = metaList.entrySet().iterator(); iterator.hasNext();) {
Map.Entry<String,String> entry = iterator.next();
String name = entry.getKey();
String value = entry.getValue();
nameValuePairs[index++] = new NameValuePair(name,value);
}
}
fis = new FileInputStream(file);
byte[] file_buff = null;
if (fis != null) {
int len = fis.available();
file_buff = new byte[len];
fis.read(file_buff);
}
fileId = Singleton.storageClient1.upload_file1(file_buff, getFileExt(file.getName()), meta_list);
} catch (Exception e) {
e.printStackTrace();
}finally {
if(fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return fileId;
}
/**
* 文件上传 返回web url
* @param file
* @return
* @throws IOException
* @throws MyException
*/
public static String uploadFileReturnUrl(File file, Map<String,String> metaList) {
String fileId = uploadFile(file,metaList);
return fdfs_web_uri+"/"+ fileId;
}
/**
* 获取文件元数据
* @param fileId 文件ID
* @return
*/
public static Map<String,String> getFileMetadata(String fileId) {
try {
NameValuePair[] metaList = Singleton.storageClient1.get_metadata1(fileId);
if (metaList != null) {
HashMap<String,String> map = new HashMap<String, String>();
for (NameValuePair metaItem : metaList) {
map.put(metaItem.getName(),metaItem.getValue());
}
return map;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 功能描述:获取文件名后缀(不包含点)
* @author dayibalang
* @date 2020/7/22
* @param fileName
* @return java.lang.String
*/
private static String getFileExt(String fileName) {
if (fileName == null || !fileName.contains(".")) {
return "";
} else {
return fileName.substring(fileName.lastIndexOf(".") + 1); // 不带最后的点
}
}
/**
* 删除文件
* @param fileId 文件ID
* @return 删除失败返回-1,否则返回0
*/
public static int deleteFile(String fileId) {
try {
return Singleton.storageClient1.delete_file1(fileId);
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}
/**
* 下载文件
* @param fileId 文件ID(上传文件成功后返回的ID)
* @param outFile 文件下载保存位置
* @return
*/
public static int downloadFile(String fileId, File outFile) {
FileOutputStream fos = null;
try {
byte[] bytes = Singleton.storageClient1.download_file1(fileId);
InputStream inputStream = new ByteArrayInputStream(bytes);
fos = new FileOutputStream(outFile);
IOUtils.copy(inputStream,fos);
return 0;
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}
}