工具类:FastDFS工具类

1、pom引用

<dependency>
    <groupId>com.github.tobato</groupId>
    <artifactId>fastdfs-client</artifactId>
    <version>1.26.2</version>
</dependency>

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>

2、上传实体

@Data
public class FSEntity implements Serializable {
    private static final long serialVersionUID = 2951336268677521004L;
    private String keyId;
    private String name;
    private transient InputStream inputstream;
    private String contentType;
    private long size;
    private Date updatedate;
    private FSAccessControlList acl;

    public FSEntity() {
    }
}

3、接口、实现

public interface FSManager {
    FSEntity getObject(String var1, String var2);

    FSEntity putObject(String var1, FSEntity var2);

    boolean deleteObject(String var1, String var2);
}
import com.github.tobato.fastdfs.domain.fdfs.FileInfo;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.domain.proto.storage.DownloadCallback;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;

public class FSStoreGenericManagerImpl implements FSManager {
    @Autowired
    private FastFileStorageClient fastFileStorageClient;

    public FSStoreGenericManagerImpl() {
    }

    public FSEntity putObject(String bucket, FSEntity fsEntity) {
        String ext = FilenameUtils.getExtension(fsEntity.getName());
        StorePath storePath = this.fastFileStorageClient.uploadFile(bucket, fsEntity.getInputstream(), fsEntity.getSize(), ext);
        fsEntity.setKeyId(storePath.getPath());
        return fsEntity;
    }

    public FSEntity getObject(String bucket, String objectId) {
        objectId = bucket + "/" + objectId;
        StorePath storePath = StorePath.parseFromUrl(objectId);
        FileInfo fileInfo = this.fastFileStorageClient.queryFileInfo(storePath.getGroup(), storePath.getPath());
        InputStream inputStream = (InputStream)this.fastFileStorageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new FSStoreGenericManagerImpl.StreamDownloadCallback());
        FSEntity fsEntity = new FSEntity();
        fsEntity.setKeyId(objectId);
        fsEntity.setInputstream(inputStream);
        fsEntity.setSize(fileInfo.getFileSize());
        fsEntity.setName(objectId);
        fsEntity.setUpdatedate((Date)null);
        fsEntity.setContentType((String)null);
        return fsEntity;
    }

    public boolean deleteObject(String bucket, String objectId) {
        objectId = bucket + "/" + objectId;
        this.fastFileStorageClient.deleteFile(objectId);
        return true;
    }

    public void setFastFileStorageClient(FastFileStorageClient fastFileStorageClient) {
        this.fastFileStorageClient = fastFileStorageClient;
    }

    public static class StreamDownloadCallback implements DownloadCallback<InputStream> {
        public StreamDownloadCallback() {
        }

        public InputStream recv(InputStream ins) throws IOException {
            return ins;
        }
    }
}

4、封装接口、实现

public interface IFSFileManager {
    String uploadFile(MultipartFile file, String fileName) throws Exception;

    FSEntity uploadFileForFsEntity(MultipartFile file, String fileName) throws Exception;

    void downloadFile(HttpServletResponse response, String fileName, String newFileName) throws Exception;

    void downloadFile(HttpServletResponse response, String contentType, InputStream inputStream, String fileName) throws Exception;

    boolean deleteFile(String bucket, String fileName);

    String getFileUrl(String fileId);

    InputStream getFileStream(String bucket, String fileName) throws Exception;

    void downloadFileForFsEntity(HttpServletResponse response, String fileId, String newFileName) throws Exception;
}
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

@Slf4j
@Service("fsFileManager")
public class FSFileManager implements IFSFileManager{

    @Autowired
    private FSManager fsManager;
    @Autowired
    private SequenceUtil sequenceUtil;
    @Value("${fsstore.url}")
    private String url;
    @Value("${fsstore.bucket}")
    private String bucket;
    @Value("${fsstore.log:false}")
    private boolean logFlag;

    @Value("${fsstore.http.url}")
    private String httpUrl;

    //路径前缀
    private final static String File_PREFIX = "smsfiles/";

    /**
     * 上传文件
     *
     * @param file     需要上传的文件
     * @param fileName 需要保存的文件名
     * @return 保存完成的文件名
     */
    @Override
    public String uploadFile(MultipartFile file, String fileName) throws Exception {
        FSEntity fsEntity = new FSEntity();
        try {
            fsEntity.setInputstream(file.getInputStream());
            fsEntity.setName(File_PREFIX + fileName);
            fsEntity.setSize(file.getSize());
            fsManager.putObject(bucket, fsEntity);
        } catch (Exception e) {
            throw new Exception("上传文件出错:" + fileName + e.getMessage());
        }
        return fsEntity.getName();
    }

    /**
     * 上传文件
     *
     * @param file
     * @param fileName
     * @return FSEntity 实体
     * @throws Exception
     */
    @Override
    public FSEntity uploadFileForFsEntity(MultipartFile file, String fileName) throws Exception {
        FSEntity fsEntity = new FSEntity();
        try {
            fsEntity.setInputstream(file.getInputStream());
            fsEntity.setName(File_PREFIX + fileName);
            fsEntity.setSize(file.getSize());
            fsManager.putObject(bucket, fsEntity);
        } catch (Exception e) {
            throw new Exception("上传文件出错:" + fileName + e.getMessage());
        }
        return fsEntity;
    }

    /**
     * 文件下载
     *
     * @param response    响应
     * @param fileName    需要下载的文件名
     * @param newFileName 下载成新的文件名
     */
    @Override
    public void downloadFile(HttpServletResponse response, String fileName, String newFileName) throws Exception {
        FSEntity fsEntity = fsManager.getObject(bucket, File_PREFIX + fileName);
        if (!ValidateUtil.isEmpty(fsEntity)) {
            InputStream inputStream = fsEntity.getInputstream();
            downloadFile(response, fsEntity.getContentType(), fsEntity.getInputstream(), newFileName);
            IOUtils.closeQuietly(inputStream);
        } else {
            throw new Exception("找不到需要下载的文件");
        }
    }

    /**
     * 文件下载
     *
     * @param response    响应
     * @param fileId    需要下载的文件id
     * @param newFileName 下载成新的文件名
     */
    @Override
    public void downloadFileForFsEntity(HttpServletResponse response, String fileId, String newFileName) throws Exception {
        FSEntity fsEntity = fsManager.getObject(bucket, fileId);
        if (!ValidateUtil.isEmpty(fsEntity)) {
            InputStream inputStream = fsEntity.getInputstream();
            downloadFile(response, fsEntity.getContentType(), fsEntity.getInputstream(), newFileName);
            IOUtils.closeQuietly(inputStream);
        } else {
            throw new Exception("找不到需要下载的文件");
        }
    }

    /**
     * 文件下载
     *
     * @param response    响应
     * @param contentType 响应内容类型
     * @param inputStream 输入流
     * @param fileName    文件名
     */
    @Override
    public void downloadFile(HttpServletResponse response, String contentType, InputStream inputStream, String fileName) throws Exception {
        OutputStream myout = null;
        try {
            String newFileName = URLEncoder.encode(fileName, "UTF-8");
            response.setCharacterEncoding("UTF-8");
            response.setContentType(contentType);
            response.addHeader("Content-Disposition", "attachment; filename=\"" + newFileName + "\"");
            BufferedInputStream input = new BufferedInputStream(inputStream);
            myout = response.getOutputStream();
            //开始循环下载
            byte[] buff = new byte[2048];
            int bytesRead;
            while (-1 != (bytesRead = input.read(buff, 0, buff.length))) {
                myout.write(buff, 0, bytesRead);
            }
            myout.flush();
        } catch (Exception e) {
            throw new Exception("下载出错:" + e.getMessage());
        } finally {
            IOUtils.closeQuietly(myout);
        }
    }

    /**
     * 删除文件
     *
     * @param fileName 需要删除的文件名
     * @return
     */
    @Override
    public boolean deleteFile(String bucket, String fileName) {
        return fsManager.deleteObject(bucket, File_PREFIX + fileName);
    }

    /**
     * 获取文件链接地址
     *
     * @param fileId
     * @return
     */
    @Override
    public String getFileUrl(String fileId) {
        return "http://" + httpUrl + "/" + bucket +"/" + fileId;
    }

    /**
     * 获取文件链接地址
     *
     * @param fileName
     * @return
     */
    public String getFileUrl(String endpoint, String fileName) {
        return "http://" + bucket + "." + endpoint + "/" + fileName;
    }

    /**
     * 获取文件流
     *
     * @param fileName 文件名
     * @return 文件输入流
     */
    @Override
    public InputStream getFileStream(String bucket, String fileName) throws Exception {
        FSEntity file = fsManager.getObject(bucket, File_PREFIX + fileName);
        if (ValidateUtil.isEmpty(file)) {
            throw new Exception("无法文件名:" + fileName + "的文件");
        }
        return file.getInputstream();
    }
}

6、配置

fsstore.bucket=group1
fsstore.url=http://xxxx:xxx/group1/
fdfs.so-timeout=1501
fsstore.http.url=xxxx:xxx
fdfs.connect-timeout=60000
fdfs.tracker-list[0]=xxxx:xxx

7、使用

public FSEntity saveUploads(MultipartFile file) {
  FSEntity fsEntity = null;
  try {
    fsEntity = ifsFileManager.uploadFileForFsEntity(file,file.getOriginalFilename());
  } catch (Exception e) {
    e.printStackTrace();
  }
  return fsEntity;
}


public static void main(String[] args){
  FSEntity fsEntity = kngMultInfoBBO.saveUploads(files);
  if(fsEntity!=null && StringUtils.isNotBlank(fsEntity.getKeyId())){
    log.info("=========="+fsEntity.getKeyId());
    log.info("http://" + httpUrl + "/" + bucket +"/" + fsEntity.getKeyId());
  }else{
    log.info("==========>"+上传失败)
  }
}
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐