如果需要用到fasfdfs,那相信对fasfdfs 有过基本的了解,原理和应用就不说了,说下核心的,怎么快速的将fasfdfs 整合到项目中来。
首先第一步,求助大神,在github上搜索fasfdfs :
跟java相关就有挺多的,第一第二的星星都比较多,我就选第一个了。
下载下来,导进本地eclipse,看看人家的源码,对源码的结构有个大致的了解,就看看测试用例,怎么使用,其实像在github的fasfdfs 工具,测试用例都会在test包中,逻辑也不难,看看就知道怎么用了。
好了,如果已经找到适合的fasfdfs 工具,接下来就是核心–整合进项目中:
1.根据readme文档,最好的方式是打包成jar,在项目的pom文件引进
2.引进之后,结合业务层的使用,将fasfdfs 的使用做成一个接口最佳,这个接口包含对fasfdfs 增删查改,开启/关闭链接,设置最高连接数
模板:
import java.io.IOException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.ProtoCommon;
import org.csource.fastdfs.StorageClient;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FastdfsHelper {
private static boolean hasInit = false;
private String groupName = "xxx";
private static Logger logger = LoggerFactory.getLogger(FastdfsHelper.class);
private MyConnectionPool connectionPool;
public FastdfsHelper(String groupName) {
connectionPool = MyConnectionPool.getConnectionPool();
this.groupName = groupName;
}
/**
* 上传html文件
*
* @param file_buff
* @return
*/
public String uploadHtmlFile(byte[] file_buff) {
return uploadFile(file_buff, "html", null);
}
/**
* 上传图片文件
*
* @param file_buff
* @param file_ext_name
* @return
*/
public String uploadImageFile(byte[] file_buff, String file_ext_name) {
return uploadFile(file_buff, file_ext_name, null);
}
/**
* 上传文件
*
* @param file_buff
* @param file_ext_name
* @param meta_list
* @return
*/
public String uploadFile(byte[] file_buff, String file_ext_name, NameValuePair[] meta_list) {
String fileName = "";
StorageClient client = null;
try {
while (true) {
client = connectionPool.checkout(1000);
if (client != null) {
break;
}
}
String[] results = client.upload_file(file_buff, file_ext_name, meta_list);
if (results == null) {
return fileName;
}
fileName = results[0] + "/" + results[1];
} catch (Exception e) {
connectionPool.drop(client);
e.printStackTrace();
} finally {
connectionPool.checkin(client);
}
return fileName;
}
/**
* 下载文件
*
* @param fullFileName
* @return
*/
public byte[] download(String fullFileName) {
byte[] buff = null;
int index = fullFileName.indexOf("/");
String group = fullFileName.substring(0, index);
String fileName = fullFileName.substring(index + 1, fullFileName.length());
StorageClient client = null;
try {
while (true) {
client = connectionPool.checkout(1000);
if (client != null) {
break;
}
}
buff = client.download_file(group, fileName);
} catch (Exception e) {
connectionPool.drop(client);
e.printStackTrace();
} finally {
connectionPool.checkin(client);
}
return buff;
}
/**
* 删除文件
*
* @param fullFileName
* @return
*/
public void Delete(String fullFileName) {
int index = fullFileName.indexOf("/");
String group = fullFileName.substring(0, index);
String fileName = fullFileName.substring(index + 1, fullFileName.length());
StorageClient client = null;
try {
while (true) {
client = connectionPool.checkout(1000);
if (client != null) {
break;
}
}
int delete_file = client.delete_file(group, fileName);
} catch (Exception e) {
connectionPool.drop(client);
e.printStackTrace();
} finally {
connectionPool.checkin(client);
}
}
}
这是集中处理连接的工具类:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;
import org.omg.CORBA.PRIVATE_MEMBER;
public class MyConnectionPool {
// 最大连接数,可以写配置文件
private int size = 128;
// 被使用的连接
private ConcurrentHashMap<StorageClient, Object> busyConnectionPool = null;
// 空闲的连接
private ArrayBlockingQueue<StorageClient> idleConnectionPool = null;
private Object obj = new Object();
private String groupName = "group1";
private static MyConnectionPool instance;
public static MyConnectionPool getConnectionPool() {
if (instance == null) {
synchronized (MyConnectionPool.class) {
if (instance == null)
instance = new MyConnectionPool();
}
}
return instance;
}
// 取出连接
public StorageClient checkout(int waitTime) {
StorageClient storageClient = null;
try {
storageClient = idleConnectionPool.poll(waitTime, TimeUnit.SECONDS);
// System.out.println(storageClient1);
if (storageClient != null) {
busyConnectionPool.put(storageClient, obj);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
storageClient = null;
e.printStackTrace();
}
return storageClient;
}
// 回收连接
public void checkin(StorageClient storageClient) {
if (busyConnectionPool.remove(storageClient) != null) {
idleConnectionPool.add(storageClient);
}
}
// 如果连接无效则抛弃,新建连接来补充到池里
public void drop(StorageClient storageClient) {
if (busyConnectionPool.remove(storageClient) != null) {
TrackerServer trackerServer = null;
StorageServer storageServer = null;
TrackerClient trackerClient = new TrackerClient();
try {
trackerServer = trackerClient.getConnection();
storageServer = trackerClient.getStoreStorage(trackerServer, groupName);
StorageClient newStorageClient = new StorageClient(trackerServer, null);
idleConnectionPool.add(newStorageClient);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (trackerServer != null) {
try {
trackerServer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (storageServer != null) {
try {
storageServer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
// 单例
private MyConnectionPool() {
busyConnectionPool = new ConcurrentHashMap<StorageClient, Object>();
idleConnectionPool = new ArrayBlockingQueue<StorageClient>(size);
init(size);
}
// 初始化连接池
private void init(int size) {
initClientGlobal();
TrackerServer trackerServer = null;
StorageServer storageServer = null;
try {
TrackerClient trackerClient = new TrackerClient();
for (int i = 0; i < size; i++) {
trackerServer = trackerClient.getConnection();
storageServer = trackerClient.getStoreStorage(trackerServer, groupName);
StorageClient storageClient = new StorageClient(trackerServer, null);
idleConnectionPool.add(storageClient);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (trackerServer != null) {
try {
trackerServer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (storageServer != null) {
try {
storageServer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 初始化客户端
private void initClientGlobal() {
String configFilePath = this.getClass().getClassLoader().getResource("xxx.properties").getPath();
try {
ClientGlobal.init(configFilePath);
} catch (Exception e) {
e.printStackTrace();
}
}
}
接下来,业务层面的代码直接调用就好,不需要关心连接的开启和关闭,也不用关心文件上传下载的内部细节。