fastdfs工具类与采坑记

一、docker安装Fastdfs

1.查找Docker Hub上的redis镜像

docker search fastdfs

2.拉取镜像

docker pull delron/fastdfs #拉取最新版本

4.使用docker镜像构建tracker容器(跟踪服务器,起到调度的作用):

docker run -dti --network=host --name tracker -v /var/fdfs/tracker:/var/fdfs -v /etc/localtime:/etc/localtime delron/fastdfs tracker

5.使用docker镜像构建storage容器(存储服务器,提供容量和备份服务):

docker run -dti  --network=host --name storage -e TRACKER_SERVER=192.168.56.1:22122 -v /var/fdfs/storage:/var/fdfs  -v /etc/localtime:/etc/localtime  delron/fastdfs storage

注意TRACKER_SERVER=外网的ip地址:22122 本机ip地址不要使用127.0.0.1
注意

. 应用系统在上传文件到FastDFS成功时将原始文件名和“文件索引(FID)”保存下来(例如:保存到数据库)。
 
二. 用户点击下载的时用Nginx的域名和FID拼出url,然后在url后面增加一个参数,指定原始文件名。例如:
http://192.168.6.124:8888/group1/M00/00/00/wKgGe15Ut3CAZcnmAA98T7dRZ0c.tar.gz?attname=shooter.tar.gz
 
三. 在Nginx上进行如下配置,这样Nginx就会截获url中的参数attname,在Http响应头里面加上字段 Content-Disposition "attachment;filename=$arg_attname"

fastdfs工具类与采坑记_第1张图片

server {
        listen       8888;
        server_name  localhost;
        location ~/group([0-9])/M00 {
            alias /data-fdfs/storage/data;
            add_header Content-Disposition "attachment;filename=$arg_attname";
            ngx_fastdfs_module;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        access_log /usr/local/nginx/logs/access.log main;
    }

进入storage容器,到storage的配置文件中配置http访问的端口,配置文件在/etc/fdfs目录下的storage.conf。
6.测试

 /usr/bin/fdfs_upload_file /etc/fdfs/client.conf test.png

二、客户端依赖

        <dependency>
            <groupId>com.roncoo</groupId>
            <artifactId>fastdfs-client-java</artifactId>
            <version>1.29</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-classic</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
		<dependency>
		    <groupId>org.csource</groupId>
		    <artifactId>fastdfs-client-java</artifactId>
		    <version>1.27-RELEASE</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-classic</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

三、工具类

import lombok.Data;

@Data
public class FastDFSFile {
    /**
     * 文件名字
     */
    private String name;
    /**
     * 文件内容
     */
    private byte[] content;
    /**
     * 文件扩展名
     */
    private String ext;
    /**
     * 文件MD5摘要值
     */
    private String md5;
    /**
     * 文件创建作者
     */
    private String author;

    /**
     * 文件长度
     */
    private Long size;


    public FastDFSFile(String name, byte[] content, String ext, String height, String width, String author) {
        super();
        this.name = name;
        this.content = content;
        this.ext = ext;
        this.author = author;
    }

    public FastDFSFile(String name, byte[] content, String ext) {
        super();
        this.name = name;
        this.content = content;
        this.ext = ext;
    }

    public FastDFSFile(byte[] content, String name, Long size){
        this.content = content;
        this.name = name;
        this.size = size;
    }
}

fastdfs客户端

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 上传对象存储数据 访问8888
 */

@Order(100)
@Slf4j
@Configuration
public class FastDfsClient implements ApplicationListener<ApplicationReadyEvent> {

    private static int dfsTrackerPoint;

    private static String dfsTrackerServer;

    private static int dfsConnectTimeout;

    private static int dfsNetworkTimeout;


    /**
     * 上传文件
     * @param file 文件对象
     * @param fileName 文件名
     * @return
     */
    public String uploadFile(File file, String fileName) {
        try {
            FileInputStream fis = new FileInputStream(file);
            byte[] fileBuff = null;
            if (fis != null) {
                int len = fis.available();
                fileBuff = new byte[len];
                fis.read(fileBuff);
            }
            FastDFSFile fastDFSFile = new FastDFSFile(fileName, fileBuff, FilenameUtils.getExtension(file.getName()));
            fis.close();
            String uploadFile = uploadFile(fastDFSFile);
            if(uploadFile != null){
                return uploadFile.concat("?").concat("attname=").concat(fileName);
            }
        }catch (Exception e){
             log.error("上传文件失败:{}",e);
        }
        return null;
    }


    /**
     * 下载文件
     * @param fileName
     * @return
     */
    public byte[] downloadFile(String fileName) {
        try {
            return getStorageClient1().download_file1(fileName);
        } catch (Exception e) {
            log.error("下载文件失败:{}", e);
        }
        return null;
    }




    /**
     * 下载文件
     * @param groupName
     * @param remoteFileName
     * @return
     */
    public static InputStream downFile(String groupName, String remoteFileName) {
        try {
            StorageClient storageClient = getStorageClient();
            byte[] fileByte = storageClient.download_file(groupName, remoteFileName);
            return new ByteArrayInputStream(fileByte);
        } catch (Exception e) {
            log.error("下载文件失败:{}",e);
        }
        return null;
    }


    /**
     * 获取文件元数据
     * @param fileId 文件ID
     * @return
     */
    public Map<String,String> getFileMetadata(String fileId) {
        try {
            NameValuePair[] metaList = getStorageClient1().get_metadata1(fileId);
            if (metaList != null) {
                HashMap<String,String> map = new HashMap<>();
                for (NameValuePair metaItem : metaList) {
                     map.put(metaItem.getName(), metaItem.getValue());
                }
                return map;
            }
        } catch (Exception e) {
            log.error("获取文件元数据失败:{}", e);
        }
        return null;
    }

    /**
     * 删除文件
     * @param fileId 文件ID
     * @return 删除失败返回-1,否则返回0
     */
    public int deleteFile(String fileId) {
        try {
            return getStorageClient1().delete_file1(fileId);
        } catch (Exception e) {
            log.error("删除文件失败:{}", e);
        }
        return -1;
    }

    /**
     * 下载文件
     * @param fileId 文件ID(上传文件成功后返回的ID)
     * @param outFile 文件下载保存位置
     * @return
     */
    public int downloadFile(String fileId, File outFile) {
        FileOutputStream fileOutputStream = null;
        ByteArrayInputStream inputStream = null;
        try {
            byte[] content = getStorageClient1().download_file1(fileId);
            inputStream = new ByteArrayInputStream(content, 1, content.length);
            fileOutputStream = new FileOutputStream(outFile);
            IOUtils.copy(inputStream, fileOutputStream);
            return 0;
        } catch (Exception e) {
            log.error("下载文件失败:{}", e);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error("下载文件完毕后, 关闭输入流失败:{}", e);
                }
            }
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    log.error("下载文件完毕后, 关闭输出流失败:{}", e);
                }
            }
        }
        return -1;
    }


    /**
     * 上传文件方法
     * 

Title: uploadFile

*

Description:

* @param fileName 文件全路径 * @param extName 文件扩展名,不包含(.) * @param metas 文件扩展信息 * @return * @throws Exception */
public String uploadFile(String fileName, String extName, NameValuePair[] metas) throws Exception { return getStorageClient1().upload_file1(fileName, extName, metas); } public String uploadFile(String fileName) throws Exception { return uploadFile(fileName, null, null); } public String uploadFile(String fileName, String extName) throws Exception { return uploadFile(fileName, extName, null); } /** * 上传文件方法 * @param fileContent 文件的内容,字节数组 * @param extName 文件扩展名 * @param metas 文件扩展信息 * @return * @throws Exception */ public String uploadFile(byte[] fileContent, String extName, NameValuePair[] metas){ try { return getTrackerUrl().concat(getStorageClient1().upload_file1(fileContent, extName, metas)); } catch (Exception e) { log.error("上传文件失败:{}", e); } return null; } public String uploadFile(byte[] fileContent, String fileName){ String uploadFile = uploadFile(fileContent, null, null); if(uploadFile != null){ return uploadFile.concat("?").concat("attname=").concat(fileName); } return null; } public String uploadExtName(byte[] fileContent, String extName){ return uploadFile(fileContent, extName, null); } /** * 生成可以访问的url * @param byteFile * @param extName * @param fileName * @return */ public String uploadFileByte(byte[] byteFile, String extName, String fileName){ NameValuePair[] naps = new NameValuePair[1]; naps[0] = new NameValuePair(fileName, extName); try { return getTrackerUrl().concat(getStorageClient1().upload_file1(byteFile, extName, naps)); } catch (Exception e) { log.error("上传文件失败:{}", e); } return null; } /** * 不生成可以访问的url * @param byteFile * @param extName * @param fileName * @return */ public String uploadFileByteKey(byte[] byteFile, String extName, String fileName){ NameValuePair[] naps = new NameValuePair[1]; naps[0] = new NameValuePair(fileName, extName); try { return getStorageClient1().upload_file1(byteFile, extName, naps); } catch (Exception e) { log.error("上传文件失败:{}", e); } return null; } /** * 下载文件 * @param groupName * @param fileName * @return 二进制流 */ public byte[] downloadBytes(String groupName, String fileName) { try { return getStorageClient1().download_file(groupName, fileName); } catch (Exception e) { log.error("下载文件失败:{}", e); } return null; } /** * 文件下载 * @param filePath 文件地址 * @param savePath 本地保存地址 */ public void download(String filePath, String savePath){ try { byte[] bytes = getStorageClient1().download_file1(filePath); IOUtils.write(bytes,new FileOutputStream(savePath)); } catch (Exception e) { log.error("文件下载失败:{}",e); } } /** * 获取文件信息 * 文件IP地址 * String sourceIpAddr = fileInfo.getSourceIpAddr(); * 文件大小 * long fileSize = fileInfo.getFileSize(); * 文件创建时间 * Date createTimestamp = fileInfo.getCreateTimestamp(); * 错误码 * long crc32 = fileInfo.getCrc32(); * @param filePath 文件的地址 * @return */ public FileInfo getFileInfo(String filePath){ try { return getStorageClient1().get_file_info1(filePath); } catch (Exception e) { log.info("获取文件信息失败:{}",e); } return null; } /** * 上传文件 * @param file * @return */ public String uploadFile(FastDFSFile file){ NameValuePair[] nameValuePairs = new NameValuePair[1]; nameValuePairs[0] = new NameValuePair(file.getAuthor()); try { return getTrackerUrl().concat(getStorageClient1().upload_file1(file.getContent(), file.getExt(),nameValuePairs)); } catch (Exception e) { log.error("upload file is fail: {} ",e.getMessage()); } return null; } /** * 下载文件 * @param path * @return 文件对象 */ public InputStream downFile(String path){ try { byte[] bytes = getStorageClient1().download_file1(path); return new ByteArrayInputStream(bytes); } catch (Exception e) { log.error("download file is fail : {}", e.getMessage()); } return null; } /** * 删除文件 * @param path */ public void deleteFilePath(String path){ try { getStorageClient1().delete_file1(path); } catch (Exception e) { log.error("delete file is fail : {}",e.getMessage()); } } /** * fastDFS文件上传 生成可以访问的url * * @param file 上传的文件 FastDFSFile * @return String 返回文件的绝对路径 */ public String uploadFastDFSFile(FastDFSFile file) { try { //文件扩展名 String ext = FilenameUtils.getExtension(file.getName()); //mata list是表文件的描述 NameValuePair[] mata_list = new NameValuePair[3]; mata_list[0] = new NameValuePair("fileName", file.getName()); mata_list[1] = new NameValuePair("fileExt", ext); mata_list[2] = new NameValuePair("fileSize", String.valueOf(file.getSize())); String url = getStorageClient1().upload_file1(file.getContent(), ext, mata_list); return getTrackerUrl().concat(url); } catch (Exception e) { log.error("上传文件失败:{}",e); } return null; } /** * 不生成 可以访问的url * @param file * @return */ public String uploadFastDFSFileKey(FastDFSFile file) { try { //文件扩展名 String ext = FilenameUtils.getExtension(file.getName()); //mata list是表文件的描述 NameValuePair[] mata_list = new NameValuePair[3]; mata_list[0] = new NameValuePair("fileName", file.getName()); mata_list[1] = new NameValuePair("fileExt", ext); mata_list[2] = new NameValuePair("fileSize", String.valueOf(file.getSize())); String url = getStorageClient1().upload_file1(file.getContent(), ext, mata_list); return getTrackerUrl().concat(url); } catch (Exception e) { log.error("上传文件失败:{}",e); } return null; } @Value("${xxx.dfsTrackerPoint}") public void setDfsTrackerPoint(int dfsTrackerPoint) { FastDfsClient.dfsTrackerPoint = dfsTrackerPoint; } @Value("${xxx.dfsTrackerServer}") public void setDfsTrackerServer(String dfsTrackerServer) { FastDfsClient.dfsTrackerServer = dfsTrackerServer; } @Value("${xxx.dfsConnectTimeout}") public void setDfsConnectTimeout(int dfsConnectTimeout) { FastDfsClient.dfsConnectTimeout = dfsConnectTimeout; } @Value("${xxx.dfsNetworkTimeout}") public void setDfsNetworkTimeout(int dfsNetworkTimeout) { FastDfsClient.dfsNetworkTimeout = dfsNetworkTimeout; } public static StorageServer[] getStoreStorages(String groupName) throws IOException { TrackerClient trackerClient = new TrackerClient(); TrackerServer trackerServer = trackerClient.getConnection(); return trackerClient.getStoreStorages(trackerServer, groupName); } public static ServerInfo[] getFetchStorages(String groupName, String remoteFileName) throws IOException { TrackerClient trackerClient = new TrackerClient(); TrackerServer trackerServer = trackerClient.getConnection(); return trackerClient.getFetchStorages(trackerServer, groupName, remoteFileName); } public static String getTrackerUrl() throws IOException { return "http://" + getTrackerServer().getInetSocketAddress().getHostString().concat(":").concat("8888").concat("/"); } private static StorageClient getStorageClient() throws IOException { TrackerServer trackerServer = getTrackerServer(); StorageClient storageClient = new StorageClient(trackerServer, null); // 连接FastDFS集群,避免出现 java.io.IOException: recv package size -1 != 10 防止30秒进行重连 //ProtoCommon.activeTest(trackerServer.getSocket()); return storageClient; } private static TrackerClient getTrackerClient() { TrackerClient trackerClient = new TrackerClient(); return trackerClient; } private static TrackerServer getTrackerServer() throws IOException { TrackerClient trackerClient = getTrackerClient(); TrackerServer trackerServer = trackerClient.getConnection(); return trackerServer; } private static StorageClient1 getStorageClient1() throws IOException { TrackerClient trackerClient = getTrackerClient(); TrackerServer trackerServer = trackerClient.getConnection(); StorageServer storageServer = trackerClient.getStoreStorage(trackerServer); StorageClient1 storageClient1 = new StorageClient1(trackerServer, storageServer); // 连接FastDFS集群,避免出现 java.io.IOException: recv package size -1 != 10 防止30秒进行重连 //ProtoCommon.activeTest(trackerServer.getSocket()); return storageClient1; } @Override public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) { try { Properties props = new Properties(); props.put(ClientGlobal.PROP_KEY_TRACKER_SERVERS, dfsTrackerServer == null ? "192.168.21.1:22122" : dfsTrackerServer); props.put(ClientGlobal.PROP_KEY_HTTP_TRACKER_HTTP_PORT, dfsTrackerPoint == 0 ? 22122 : dfsTrackerPoint); props.put(ClientGlobal.PROP_KEY_CHARSET, "UTF-8"); props.put(ClientGlobal.PROP_KEY_HTTP_SECRET_KEY, "FastDFS1234567890"); props.put(ClientGlobal.PROP_KEY_HTTP_ANTI_STEAL_TOKEN, false); //加载连接信息 ClientGlobal.initByProperties(props); }catch (Exception e){ log.error("初始化配置失败:{}", e); } } }

你可能感兴趣的:(JAVA开发,fastdfs工具类与采坑记,docker,fastdfs,fastdfs工具类,FastDfs工具类)