前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >手把手fastDFS实战2-文件读写

手把手fastDFS实战2-文件读写

原创
作者头像
技术路漫漫
修改2020-06-22 10:50:18
5060
修改2020-06-22 10:50:18
举报
文章被收录于专栏:技术路漫漫技术路漫漫

本文在上篇搭建了fastDFS服务的基础上,基于其javaClient,实现文件的上传、下载、删除和信息获取、展示等功能。

maven依赖引入

在常用的maven仓库中,搜索不到仓库信息,只能down源码后自己构建并导入:

代码语言:txt
复制
<dependency>
    <groupId>org.csource</groupId>
    <artifactId>fastdfs-client-java</artifactId>
    <version>1.29-SNAPSHOT</version>
</dependency>

fdfs_client.properties配置

具体配置如下:

代码语言:txt
复制
fastdfs.connect_timeout_in_seconds=5
fastdfs.network_timeout_in_seconds=30
fastdfs.charset=UTF-8
fastdfs.http_anti_steal_token=false
#http_secret_key等要与服务端配置保持一致
fastdfs.http_secret_key=goodFS
fastdfs.http_tracker_http_port=8080
fastdfs.tracker_servers=192.168.0.124:22122
fastdfs.connection_pool.enabled=true
fastdfs.connection_pool.max_count_per_entry=500
fastdfs.connection_pool.max_idle_time=3600
fastdfs.connection_pool.max_wait_time_in_ms=1000

服务端功能实现

首先,定义一个FastDfsFile类

代码语言:txt
复制
@Data
@AllArgsConstructor
@Builder
public class FastDfsFile {

    private String name;

    private byte[] content;

    /** 文件扩展名,不包含. */
    private String extName;
}

对配置进行管理:

代码语言:txt
复制
@Configuration
@Slf4j
public class FastDfsConfig {

    public FastDfsConfig() {
        // 进行属性初始化
        try {
            ClientGlobal.initByProperties("fdfs_client.properties");
        } catch (IOException | MyException e) {
            log.error("fdfs_client属性文件初始化出错", e);
        }
    }

    @Bean
    public StorageClient storageClient() throws IOException {
        TrackerClient trackerClient = new TrackerClient();
        TrackerServer trackerServer = trackerClient.getTrackerServer();
        return new StorageClient(trackerServer, null);
    }
}

编写文件上传下载客户端类:

代码语言:txt
复制
@Component
@Slf4j
public class FastDfsClient {

    @Autowired
    private StorageClient storageClient;

    public Optional<String[]> upload(FastDfsFile file) {
        log.info("start update {}", file.getName());
        NameValuePair[] metaList = new NameValuePair[1];
        metaList[0] = new NameValuePair("fileName", file.getName());

        try {
            return Optional.ofNullable(storageClient.upload_file(file.getContent(), file.getExtName(), metaList));
        } catch (IOException | MyException e) {
            log.error("上传文件出错", e);
            return Optional.empty();
        }
    }

    public Optional<FileInfo> getFileInfo(String groupName, String remoteFileName) {
        try {
            return Optional.ofNullable(storageClient.get_file_info(groupName, remoteFileName));
        } catch (IOException | MyException e) {
            log.error("获取文件信息错误", e);
            return Optional.empty();
        }
    }

    public String getFileUrl(String groupName, String remoteFileName) {
        Optional<FileInfo> fileInfo = getFileInfo(groupName, remoteFileName);
        if (fileInfo.isPresent()) {
            String url = "http://" + fileInfo.get().getSourceIpAddr() + "/" + remoteFileName;
            log.info("file url:{}", url);
            return url;
        } else {
            return "";
        }
    }

    public Optional<byte[]> download(String groupName, String remoteFileName) {
        try {
            return Optional.ofNullable(storageClient.download_file(groupName, remoteFileName));
        } catch (IOException | MyException e) {
            log.error("下载文件出错", e);
            return Optional.empty();
        }
    }

    public boolean deleteFile(String groupName, String remoteFileName) {
        try {
            return storageClient.delete_file(groupName, remoteFileName) == 0;
        } catch (IOException | MyException e) {
            log.error("删除文件出错", e);
            return false;
        }
    }

}

编写控制器类,实现对请求的处理:

代码语言:txt
复制
@Controller
@RequestMapping("/file")
@Slf4j
public class FileController {

    @Autowired
    private FastDfsClient fastDfsClient;

    @GetMapping("/")
    public String index() {
        return "fileIndex";
    }

    @PostMapping("/upload")
    public String fileUpload(@RequestParam("upFile") MultipartFile file, RedirectAttributes reAttrib) {
        if (file.isEmpty()) {
            reAttrib.addFlashAttribute("msg", "请上传一个文件");
            return "redirect:/file/fileMsg";
        }
        String fileName = file.getOriginalFilename();
        String extName = fileName.substring(fileName.lastIndexOf('.') + 1);
        try {
            byte[] content = file.getBytes();
            //构建上传文件对象
            FastDfsFile fastDfsFile = FastDfsFile.builder().content(content).extName(extName).name(fileName).build();
            // 进行文件上传
            Optional<String[]> result = fastDfsClient.upload(fastDfsFile);
            String msg = "";
            String url = "";
            if (result.isPresent()) {
                String[] results = result.get();
                msg = Arrays.toString(results);
                log.info("上传返回结果:{}", msg);
                log.info("文件详细信息:{}", fastDfsClient.getFileInfo(results[0], results[1]));
                url = fastDfsClient.getFileUrl(results[0], results[1]);
            }
            reAttrib.addFlashAttribute("msg", msg);
            reAttrib.addFlashAttribute("url", url);
            return "redirect:/file/fileMsg";
        } catch (IOException e) {
            log.error("获取文件内容出错", e);
            reAttrib.addFlashAttribute("msg", "获取文件内容出错");
            return "redirect:/file/fileMsg";
        }
    }

    @GetMapping("/fileMsg")
    public String fileMsg() {
        return "fileMsg";
    }

}

前端功能实现

主要是基于 thymeleaf进行简单内容展示:

fileIndex.html文件:

代码语言:txt
复制
<!DOCTYPE html>
<html>
<head>
    <meta content="text/html; charset=UTF-8"/>
</head>
<body>
<h1>请上传文件</h1>
<form method="post" action="/file/upload" enctype="multipart/form-data">
    <input type="file" name="upFile"/><br>
    <input type="submit" value="上传"/>
</form>
</body>
</html>

fileMsg.html文件展示结果:

代码语言:txt
复制
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta content="text/html; charset=UTF-8"/>
</head>
<body>
<h1>文件上传结果展示</h1>
<div th:if="${msg}">
    <h2 th:text="${msg}"></h2>
</div>
<div th:if="${url}">
    <img th:src="${url}">
</div>
</body>
</html>

功能测试

启动服务以后,可通过 http://localhost:8080/file/ 来访问首页

首页
首页

上传图片文件后即可进入详情页:

图片详情展示
图片详情展示

除了直接通过前端页面来测试之外,也可以通过test用例来验证结果:

代码语言:txt
复制
@SpringBootTest
@Slf4j
public class FastDfsClientTest {

    @Autowired
    private FastDfsClient client;

    @Test
    void fullTest() throws IOException, InterruptedException {
        //上传测试
        Path path = Paths.get("D:\\test\\love.png");
        byte[] content = Files.readAllBytes(path);
        FastDfsFile dfsFile = FastDfsFile.builder().content(content).name("love.png").extName("png").build();
        String[] result = client.upload(dfsFile).get();
        log.info("uploaded result:{}", Arrays.toString(result));

        String groupName = result[0];
        String remoteFileName = result[1];

        //获取文件信息测试
        log.info("fileinfo:{}", client.getFileInfo(groupName, remoteFileName));

        // 下载测试
        Optional<byte[]> bytes = client.download(groupName, remoteFileName);
        if (bytes.isPresent()) {
            String outFileName = System.currentTimeMillis() + ".png";
            Path outFile = Paths.get("D:\\test\\" + outFileName);
            if (Files.notExists(outFile)) {
                Files.createFile(outFile);
            }
            Files.write(outFile, bytes.get(), StandardOpenOption.WRITE);
        }

        // 删除测试
        log.info("delete:{}", client.deleteFile(groupName, remoteFileName));
        //注意删除后,还是可以通过getFileInfo获取到信息,只是无法再下载到,所以此处以download来验证删除结果
        log.info("fileinfo:{}", client.download(groupName, remoteFileName).isPresent());
    }
}

参考资料

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • maven依赖引入
  • fdfs_client.properties配置
  • 服务端功能实现
  • 前端功能实现
  • 功能测试
  • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档