客户端访问Tracker
Tracker 返回Storage的ip和端口
客户端直接访问Storage,把文件内容和元数据发送过去。
Storage返回文件存储id。包含了组名和文件名
- <dependencies>
- <dependency>
- <groupId>cn.bestwugroupId>
- <artifactId>fastdfs-client-javaartifactId>
- <version>1.27version>
- dependency>
- <dependency>
- <groupId>org.apache.commonsgroupId>
- <artifactId>commons-lang3artifactId>
- <version>3.4version>
- dependency>
- dependencies> `
文件名:fdfs_client.conf
修改成自己的tracker服务器ip
- connect_timeout = 10
- network_timeout = 30
- charset = UTF-8
- http.tracker_http_port = 8080
- tracker_server = 192.168.93.10:22122
3 导入工具类
在com.utils.FastDFSClient 下粘贴配置工具类
- package com.msb.utils;
- import java.io.ByteArrayInputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.InputStream;
-
- import org.apache.commons.lang3.StringUtils;
- import org.csource.common.NameValuePair;
- import org.csource.fastdfs.ClientGlobal;
- import org.csource.fastdfs.StorageClient;
- import org.csource.fastdfs.StorageClient1;
- import org.csource.fastdfs.StorageServer;
- import org.csource.fastdfs.TrackerClient;
- import org.csource.fastdfs.TrackerServer;
-
- /**
- * FastDFS分布式文件系统操作客户端.
- */
- 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); // 不带最后的点
- }
- }
- }
4 编写测试代码
随意新建一个包含主方法的类。com.msb.MyMain
- public class MyMain {
- public static void main(String[] args) {
- try {
- File file = new File("D:/b.png");
- InputStream is = new FileInputStream(file);
- String fileName = UUID.randomUUID().toString()+".png";
- String[] result = FastDFSClient.uploadFile(is, fileName);
- System.out.println(Arrays.toString(result));
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- }
- }
2 下载说明
client询问tracker下载文件的storage,参数为文件标识(组名和文件名);
tracker返回一台可用的storage;
client直接和storage通讯完成文件下载。
3 代码实现
直接使用工具方法完成下载。
- try {
- InputStream is = FastDFSClient.downloadFile("group1", "M00/00/00/wKg0gF3zAKCARs6kAAASjQVYlWA098.png");
- OutputStream os = new FileOutputStream(new File("D:/jqk.png"));
- int index = 0 ;
- while((index = is.read())!=-1){
- os.write(index);
- }
- os.flush();
- os.close();
- is.close();
- } catch (IOException e) {
- e.printStackTrace();
- }