SpringBoot重點詳解--集成FastDFS(一)

一、Maven依賴

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- 引入fastdfs客戶端依賴 -->
        <dependency>
            <groupId>org.csource</groupId>
            <artifactId>fastdfs-client-java</artifactId>
            <version>1.27-SNAPSHOT</version>
        </dependency>

    </dependencies>

遇到 fastdfs-client-java 依賴無法引入的異常,可參考 《解決 Maven 無法下載 fastdfs-client-java 依賴》

二、FastDFS客戶端配置

src\main\resources 新建一個FastDFS客戶端配置文件(fdfs_client.conf),內容如下:

connect_timeout = 5000
network_timeout = 30000
charset = UTF-8

# Tracker配置文件 /etc/fdfs/tracker.conf 中配置的http端口
http.tracker_http_port = 8080
http.anti_steal_token = false
http.secret_key = FastDFS1234567890

# Tracker服務器地址,可以寫多個
tracker_server = 172.16.250.238:22122
#tracker_server = 172.16.250.240:22122

三、封裝FdfsUtil工具類

package com.pengjunlee.utils;


import org.csource.fastdfs.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;

import java.io.*;

/**
 * Fast DFS系統文件操作上傳、下載客戶端類
 *
 * @author pengjunlee
 * @create 2019-09-17 10:25
 */

public class FdfsUtil {

    private static Logger logger = LoggerFactory.getLogger(FdfsUtil.class);

    private static StorageClient1 client;

    static {
        try {
            String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();
            ClientGlobal.init(filePath);
            TrackerClient trackerClient = new TrackerClient();
            TrackerServer trackerServer = trackerClient.getConnection();
            StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);
            client = new StorageClient1(trackerServer, storageServer);
        } catch (Exception e) {
            logger.error("FastDFS init failure!");
        }
    }

    /**
     * 上傳一個本地文件到分佈式中
     *
     * @param file
     * @return
     * @throws Exception
     */
    public static String upload(File file) throws Exception {
        return upload(new FileInputStream(file), file.getName(), file.length());
    }

    /**
     * 上傳一個流,調用後in會自動關閉
     *
     * @param in
     * @param fileName
     * @param fileSize
     * @return
     * @throws Exception
     */
    public static String upload(InputStream in, String fileName, long fileSize) throws Exception {
        try {
            String extName = fileExt(fileName);
            String ret = client.upload_appender_file1(null, fileSize, new UploadStream(in, fileSize), extName, null);
            if (ret == null) {
                throw new IOException("upload fileName:" + fileName + " error");
            }
            return ret;
        } finally {
            in.close();
        }
    }

    /**
     * 把本地文件追加到分佈式文件系統中
     *
     * @param file
     * @param dfsPath
     * @return
     * @throws Exception
     */
    public static long append(File file, String dfsPath) throws Exception {
        return append(new FileInputStream(file), dfsPath, file.length());
    }

    /**
     * 追加文件,in會被關閉
     *
     * @param in
     * @param dfsPath
     * @param appendSize
     * @return
     * @throws Exception
     */
    public static long append(InputStream in, String dfsPath, long appendSize) throws Exception {
        try {
            int ret = client.append_file1(dfsPath, appendSize, new UploadStream(in, appendSize));
            if (ret != 0) {
                throw new IOException("uploadAppend dfsPath:" + dfsPath + " error");
            }
            return appendSize;
        } finally {
            in.close();
        }
    }

    /**
     * 下載文件,方法調用後,out會被強制關閉
     *
     * @param out
     * @param dfsPath
     * @return
     * @throws Exception
     */
    public static long download(OutputStream out, String dfsPath) throws Exception {
        try {
            DownloadStream downloadStream = new DownloadStream(out);
            int ret = client.download_file1(dfsPath, downloadStream);
            if (ret != 0) {
                throw new IOException("download dfsPath:" + dfsPath + " error");
            }
            return downloadStream.downloadSize;
        } finally {
            out.close();
        }
    }

    /**
     * 下載文件,方法調用後,out會被強制關閉
     *
     * @param out
     * @param dfsPath
     * @return
     * @throws Exception
     */
    public static long download(OutputStream out, String dfsPath, long offset, long bytes) throws Exception {
        try {
            DownloadStream downloadStream = new DownloadStream(out);
            int ret = client.download_file1(dfsPath, offset, bytes, downloadStream);
            if (ret != 0) {
                throw new IOException("download dfsPath:" + dfsPath + " error");
            }
            return downloadStream.downloadSize;
        } finally {
            out.close();
        }
    }

    /**
     * 刪除指定位置文件
     *
     * @param dfsPath
     * @throws Exception
     */
    public static void delete(String dfsPath) throws Exception {
        int ret = client.delete_file1(dfsPath);
        if (ret != 0)
            throw new IOException("delete dfsPath:" + dfsPath + " error");
    }

    /**
     * 獲取文件大小;返回負數表示文件不存在,其中-1表示正常情況文件不存在,-2表示出異常了
     *
     * @param dfsPath
     * @return
     * @throws Exception
     */
    public static long length(String dfsPath) {
        try {
            FileInfo fileInfo = client.get_file_info1(dfsPath);
            if (fileInfo == null) {
                return -1;
            }
            return fileInfo.getFileSize();
        } catch (Throwable ex) {
            return -2;
        }
    }

    /**
     * 判斷Fast是否存在指定路徑的文件信息
     *
     * @param dfsPath
     * @return
     * @throws Exception
     */
    public static boolean exists(String dfsPath) throws Exception {
        if (dfsPath == null || dfsPath.trim().length() == 0) {
            return false;
        }

        try {
            FileInfo fileInfo = client.get_file_info1(dfsPath);
            return fileInfo != null;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 從路徑中提取文件後綴名,不帶句號
     *
     * @param fileName
     * @return
     */
    private static String fileExt(String fileName) {
        if (fileName == null)
            return "";

        int dot = fileName.lastIndexOf(".");
        if (dot == -1)
            return "";

        String ret = fileName.substring(dot + 1);
        for (int i = 0; i < ret.length(); i++) {
            char c = ret.charAt(i);
            boolean isAlpha = ('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
            if (!isAlpha) {
                return "";
            }
        }
        return ret;
    }

    private static class DownloadStream implements DownloadCallback {

        private long downloadSize = 0L;

        private OutputStream out;

        public DownloadStream(OutputStream out) {
            this.out = out;
        }

        public int recv(long fileSize, byte[] data, int bytes) {
            try {
                this.out.write(data, 0, bytes);
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
            this.downloadSize += bytes;
            return 0;
        }
    }
}

四、Junit測試

import com.pengjunlee.utils.FdfsUtil;
import org.junit.Test;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class FdfsTests {

    /**
     * 文件上傳測試
     */
    @Test
    public void testUpload() {
        File file = new File("C:\\1.jpg");
        try {
            String fdfsPath = FdfsUtil.upload(file);
            System.out.println("文件上傳成功,文件ID: " + fdfsPath); // 文件ID: group1/M00/00/00/rBD67l2BM0mEP2WXAAAAABISex8406.jpg
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 文件下載測試
     */
    @Test
    public void testDownload() throws FileNotFoundException {
        try {
            long downloadSize = FdfsUtil.download(new FileOutputStream(new File("C:\\1_bak.jpg")), "group1/M00/00/00/rBD67l2BM0mEP2WXAAAAABISex8406.jpg");
            System.out.println("文件下載完成,文件大小(單位 byte): " + downloadSize);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 文件刪除測試
     */
    @Test
    public void testDelete() {
        try {
            FdfsUtil.delete("group1/M00/00/00/rBD67l2BM0mEP2WXAAAAABISex8406.jpg");
            boolean exists = FdfsUtil.exists("group1/M00/00/00/rBD67l2BM0mEP2WXAAAAABISex8406.jpg");
            System.out.println("文件是否還存在: " + exists);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章