赞
踩
参考:https://gitee.com/zwlan/renewFastdfs
1. maven依赖
- <!--<fast.clent.version>1.26.2</fast.clent.version>-->
- <!--<hutool.all.version>4.0.12</hutool.all.version>-->
- <dependency>
- <groupId>cn.hutool</groupId>
- <artifactId>hutool-all</artifactId>
- <version>${hutool.all.version}</version>
- </dependency>
-
- <dependency>
- <groupId>com.github.tobato</groupId>
- <artifactId>fastdfs-client</artifactId>
- <version>${fast.clent.version}</version>
- </dependency>
2. 部分配置
#redis
spring:
redis:
open: true # 是否开启redis缓存 true开启 false关闭
database: 0
host: xx.xx.xx.xx # ip
port: xxxx # port
password: # 密码(默认为空)
timeout: 6000ms # 连接超时时长(毫秒)
jedis:
pool:
max-active: 1000 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 10 # 连接池中的最大空闲连接
min-idle: 5 # 连接池中的最小空闲连接
- #FastDFS Client
- fdfs:
- so-timeout: 1501
- connect-timeout: 601
- thumb-image: #缩略图生成参数
- width: 150
- height: 150
- tracker-list: #TrackerList参数,支持多个
- - xx.xx.xx.xx:22122 #ip:port
- pool:
- max-total: 153
- jmx-name-base: 1
- jmx-name-prefix: 1
# nginx 反向代理之后的查看资源路径
fastDFS:
file:
server:
url: http://xx.xx.xx.xx:8091 # ip:port
show:
url: http://xx.xx.xx.xx:8090
#FastDFS临时上传路径
file:
upload:
temp:
path: /data0/fastdfs/temp
3. 代码
package cn.longrace.wisdom.modules.uploader.controller; import cn.hutool.core.io.FileUtil; import cn.longrace.wisdom.common.utils.RedisUtils; import cn.longrace.wisdom.common.vo.R; import cn.longrace.wisdom.modules.sys.controller.AbstractController; import cn.longrace.wisdom.modules.uploader.common.UpLoadConstant; import cn.longrace.wisdom.modules.uploader.entity.Chunk; import cn.longrace.wisdom.modules.uploader.entity.FileInfo; import cn.longrace.wisdom.modules.uploader.service.ChunkService; import cn.longrace.wisdom.modules.uploader.service.FileInfoService; import cn.longrace.wisdom.modules.uploader.util.FileUtils; import com.github.tobato.fastdfs.domain.StorePath; import com.github.tobato.fastdfs.service.AppendFileStorageClient; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Random; import static cn.longrace.wisdom.modules.uploader.util.FileUtils.generatePath; /** * @author * @date */ @RestController @RequestMapping("/new/uploader") @Slf4j public class NewUploadController extends AbstractController { @Value("${fastDFS.file.server.url}") private String fileUploadUrl; @Value("${fastDFS.file.show.url}") private String showFileUploadUrl; @Value("${file.upload.temp.path}") private String uploadFolder; @Autowired private AppendFileStorageClient appendFileStorageClient; private Long curriculumId; @Resource private ChunkService chunkService; @Autowired RedisUtils redisUtils; @Autowired FileInfoService fileInfoService; /** * 方式一: * 功能描述:上传文件 * * @param: * @return: * @auther: * @date: */ @PostMapping("/chunk") public String uploadChunk(Chunk chunk) { MultipartFile file = chunk.getFile(); log.debug("file originName: {}, chunkNumber: {}", file.getOriginalFilename(), chunk.getChunkNumber()); try { String contentType = file.getContentType(); chunk.setType(contentType); byte[] bytes = file.getBytes(); Path p1 = Paths.get(generatePath(uploadFolder, chunk)); //文件写入指定路径 Path p = Files.write(p1, bytes); log.debug("文件 {} 写入成功, uuid:{}", chunk.getFilename(), chunk.getIdentifier()); StorePath path = null; try { File f = p.toFile(); if (redisUtils.get(chunk.getIdentifier()) == null) { // 创建可续传的文件 path = appendFileStorageClient.uploadAppenderFile(UpLoadConstant.DEFAULT_GROUP, new FileInputStream(f), f.length(), FileUtil.extName(chunk.getFilename())); redisUtils.set(chunk.getIdentifier(), path.getPath()); } else { // 最后一个参数记录文件的偏移量 appendFileStorageClient.modifyFile(UpLoadConstant.DEFAULT_GROUP, redisUtils.get(chunk.getIdentifier()), new FileInputStream(f), f.length(),(chunk.getChunkNumber() -1)*(10*1024*1024)); } } catch (Exception e) { e.printStackTrace(); } // 保存chunk Random rn = new Random(1000); chunk.setId(rn.nextLong()); chunk.setCreator(this.getUserId()); chunk.setCurriculumId(curriculumId); chunkService.saveChunk(chunk); return "文件上传成功"; }catch (Exception e) { e.printStackTrace(); return "后端异常..."; } } @GetMapping("/chunk") public Object checkChunk(Chunk chunk, HttpServletResponse response) { curriculumId = chunk.getCurriculumId(); if (chunkService.checkChunk(chunk)) { response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); } return chunk; } @PostMapping("/mergeFile") public R test (FileInfo fileInfo) throws Exception { // TODO 截图一---------------------- String filePath = showFileUploadUrl + "/"+ UpLoadConstant.DEFAULT_GROUP + "/" + redisUtils.get(fileInfo.getIdentifier()); String filename = fileInfo.getFileName(); String extension = filename.substring(filename.indexOf('.') + 1, filename.length()); String finalExtension = "mp4"; try { if (!StringUtils.isEmpty(extension) && extension.equals(finalExtension)) { System.out.println("==============视频截图开始================"); String imgFileName = filename + ".jpg"; String imgFilePath = uploadFolder + "/" + filename + ".jpg"; FileUtils.fetchFrame(filePath, imgFilePath); File tempImgFile = new File(imgFilePath); // FileInputStream fileImgInputStream = new FileInputStream(tempImgFile); // MultipartFile multipartImgFile = new MockMultipartFile(imgFileName, imgFileName, // ContentType.APPLICATION_OCTET_STREAM.toString(), fileImgInputStream); // // String jsonImgStr = HttpUtils.upload(fileUploadUrl, multipartImgFile); // System.out.println("jsonImgStr-------------------------"+jsonImgStr); StorePath path = appendFileStorageClient.uploadAppenderFile(UpLoadConstant.DEFAULT_GROUP, new FileInputStream(tempImgFile), tempImgFile.length(), FileUtil.extName(imgFileName)); fileInfo.setImgLocation(UpLoadConstant.DEFAULT_GROUP + "/" + path.getPath()); tempImgFile.delete(); } } catch (Exception e) { throw new RuntimeException(e); } System.out.println("==============视频截图结束================"); // UpLoadConstant.DEFAULT_GROUP 即group1 fileInfo.setLocation(UpLoadConstant.DEFAULT_GROUP + "/" + redisUtils.get(fileInfo.getIdentifier())); this.fileInfoService.insert(fileInfo); // 删除redis中文件key redisUtils.delete(fileInfo.getIdentifier()); // 删除临时文件目录 FileUtils.deleteDir(new File(uploadFolder + "/" + fileInfo.getIdentifier())); return R.ok().put("fileInfo",fileInfo); } }
4. 相关实体类
package cn.longrace.wisdom.modules.uploader.entity; import com.baomidou.mybatisplus.annotations.TableField; import com.baomidou.mybatisplus.annotations.TableName; import lombok.Data; import org.springframework.web.multipart.MultipartFile; import java.io.Serializable; /** * 文件分块大小 */ @Data @TableName("lr_teacher_resource_chunk") public class Chunk implements Serializable { private Long id; /** * 当前文件块,从1开始 */ private Integer chunkNumber; /** * 分块大小 */ private Long chunkSize; /** * 当前分块大小 */ private Long currentChunkSize; /** * 总大小 */ private Long totalSize; /** * 文件标识 */ private String identifier; /** * 文件名 */ private String filename; /** * 相对路径 */ private String relativePath; /** * 总块数 */ private Integer totalChunks; /** * 文件类型 */ private String type; /** * 课程ID */ private Long curriculumId; /** * 创建人 */ private Long creator; /** * 所属备课ID */ private Long prepareId; /** * 所属班级ID */ private Long classId; @TableField(exist = false) private MultipartFile file; }
package cn.longrace.wisdom.modules.uploader.entity; import com.baomidou.mybatisplus.annotations.TableName; import lombok.Data; import java.io.Serializable; /** * 文件信息实体类 */ @Data @TableName("lr_teacher_resource_file_info") public class FileInfo implements Serializable { private Long id; /** * 文件名称 */ private String fileName; /** * 文件标识 */ private String identifier; /** * 文件总大小 */ private Long totalSize; /** * 文件类型 */ private String type; /** * 文件路径 */ private String location; /** * 视频文件封面路径 */ private String imgLocation; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。