java中使用FastDFS

1,183 阅读7分钟

FastDFS文件系统Java客户端是指采用Java语言编写的一套程序,专门用来访问fastDFS文件系统,其实就是一个jar包。

一、打包jar

由于maven中央仓库没有fastdfs-client-java的jar包,所以需要从官方下载FastDFS源代码到本地,然后安装到本地仓库

下载地址,格式是.zip:codeload.github.com/happyfish10…

下载完毕后解压,解压完毕后可以看到是一个maven项目,可以直接采用maven命令编译成jar安装到本地maven库

mvn clean install

也可以导入到IDEA中再进行安装

这是我打好的包:download.csdn.net/download/zy…

二、上传、下载与删除实现

(1)添加依赖

在FastDFS源码中,找到maven坐标,添加到自己的项目中(已经安装到本地仓库)

<dependency>
    <groupId>org.csource</groupId>
    <artifactId>fastdfs-client-java</artifactId>
    <version>1.27-SNAPSHOT</version>
</dependency>

(2)配置

新建一个配置类,我起名为fastdfs.conf,在该文件中指定跟踪器的地址:

tracker_server=192.168.29.128:22122

(3)上传

固定步骤:

  • 加载(2)中建的配置文件

  • 通过一系列固定步骤,获取到Storage的客户端对象StorageClient,通过该对象来操作FastDFS

  • 上传常用的方法,方法2在web中常用:

    String[] upload_appender_file(String local_filename, String file_ext_name, NameValuePair[] meta_list)
    
    • 参数 1 为需要上传的文件在本地磁盘的绝对路径
    • 参数 2 为需要上传的文件的扩展名
    • 参数 3 为需要上传的文件的属性文件,通常为null不上传,这些文件的属性例如文件大小以及类型等信息通常需要记录到数据库中
    String[] upload_appender_file(byte[] file_buff, String file_ext_name, NameValuePair[] meta_list)
    
    • 参数 1 为需要上传的文件的字节流
    • 参数 2和3 同上
  • 方法返回一个字符串数组,数组中的值表示了文件在FastDFS中存储的位置

    • 下标为0的字符串:保存的是文件存储的组名
    • 下标为1的字符串:保存的是文件在FastDFS中存储的名字
  • 关闭可以关闭的

public static void upload() {
	TrackerServer ts = null;
    StorageServer ss = null;
    try {
        //加载配置文件,目的是为了获取所有的TrackerServer的地址信息
        ClientGlobal.init("fastdfs.conf");
        TrackerClient tc = new TrackerClient();
        ts = tc.getConnection();
        ss = tc.getStoreStorage(ts);
        //创建Storage的客户端对象,需要利用这个对象来操作FastDFS,实现文件的上传下载和删除
        StorageClient sc = new StorageClient(ts, ss);
        //上传文件到FastDFS
        //参数 1 为需要上传的文件在本地磁盘的绝对路径
        //参数 2 为需要上传的文件的扩展名
        //参数 3 为需要上传的文件的属性文件通常为null不上传,这些文件的属性例如文件大小以及类型等信息通常需要记录到数据库中
        //返回一个字符串数组,这个数组中的数据非常重要必须要妥善保管
        //注意:这个数组中的第一个元素为文件所在的FastDFS的组名,第二个元素为文件在FastDFS中的远程文件名称
        //   这两个数据通常我们是需要写入到数据库中的
        String[] result = sc.upload_file("d:/qrcode.jpg", "jpg", null);
        for (String str : result) {
            System.out.println(str);
        }

    } catch (IOException e) {
        e.printStackTrace();
    } catch (MyException e) {
        e.printStackTrace();
    } finally {
        if (ss != null) {
            try {
                ss.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (ts != null) {
            try {
                ts.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

(4)下载与删除

大部分步骤与上传一样,只是调用了Storage的客户端对象StorageClient的不同方法:

下载:

  • 方法1:
    int download_file(String group_name, String remote_filename, String local_filename)
    
    • 参数 1:文件在FastDFS中的组名
    • 参数 2:文件在FastDFS中的远程文件名
    • 参数 3:文件需要保存到本地磁盘的某个绝对路径
    • 返回值为 int 类型的整数,0表示下载文件成功,不为0表示不成功,具体的数字代表了不成功的原因
  • 方法2,web中常用:
    byte[] download_file(String group_name, String remote_filename)
    
    • 参数 1:文件在FastDFS中的组名
    • 参数 2:文件在FastDFS中的远程文件名
    • 返回值为byte数组类型,表示文件的具体内容

删除:

int delete_file(String group_name, String remote_filename)
  • 参数 1 为文件在FastDFS中的组名
  • 参数 2 为文件在FastDFS中的远程文件名
  • 返回值为 int 类型的整数,0表示删除成功

三、web中前端上传与下载文件

需要添加依赖,同2.1,这里就不细说了

1. 配置文件上传大小

SpringBoot中设置SpringMVC上传文件大小 的限制:

#如果需要修改SpringMVC上传文件的限制那么尽可能同时修改以下2个属性
#设置SpringMVC允许上传时的单个文件大小默认为 1MB
spring.servlet.multipart.max-file-size=1MB
#设置SpringMVC每个请求允许上传的文件总大小默认值为 10MB
spring.servlet.multipart.max-request-size=10MB

2. 前端上传文件

如果表单中拥有文件那么

  • method 必须是 post
  • enctype 必须是multipart/form-data
<form th:action="@{|/upload|}" method="post" enctype="multipart/form-data">
	<input type="file" name="uploadFile"><br>
	<input type="submit" value="上传文件">
</form>

小技巧:使用隐藏的<iframe>实现同步请求模拟出ajax请求的效果,不刷新页面

  1. 在页面中加入<iframe name="success" style="display: none"></iframe>
  2. 在form表单中添加参数:target="success",指向<iframe>
  3. 后台返回的页面中有如下函数:
<script>
	if(confirm("[[${message}]]")){
		window.top.location.href="当前页面"
	}
</script> 

3. 后台接收文件

后台处理传递回来的文件,要在Controller层将文件存入FastDFS,原因有二:

  • MultipartFile这个类来自于springframework.web包下的,是web组件,按照MVC的层次关系,MultipartFile只能在Controller层使用
  • 如果要传到Service层(Service可能是远程服务器),需要把字节流也传到Service层,过于耗费资源,不现实

后台使用MultipartFile对象来接收前台传输过来的文件,MultipartFile 是Spring提供的一个类,作用是用于封装请求中的文件域中的数据。

MultipartFile对象的方法:

byte[] b = uploadFile.getBytes();				//获取文件所对应的字节数组
String type = uploadFile.getContentType();		//获取文件类型,例如:图片类型:image/jpeg
InputStream in = uploadFile.getInputStream();	//获取文件所对应的输入流
String remoteName = uploadFile.getName();		//获取文件域的name属性(MultipartFile对象的名字),例如:uploadFile
String name = uploadFile.getOriginalFilename();	//获取文件的名字,例如:aaa.jpg
long size = uploadFile.getSize();				//获取文件大小
boolean b = uploadFile.isEmpty()				//判断文件是否为空,没有上传文件或文件大小为0,返回值为true表示文件为空

将接收的文件存入到FastDFS中:

@RequestMapping("/upload")
public String upload(MultipartFile uploadFile) throws IOException {
	//获取文件名字,并从文件名字中截取后缀名
	String fileName = uploadFile.getOriginalFilename();
	String fileExtName = fileName.substring(fileName.lastIndexOf(".") + 1);
	
	//将文件上传到FastDFS中(这里只是将2.3中的第二个方法封装成了工具类)
	String result[] = FastDFSUtils.upload(uploadFile.getBytes(), fileExtName);
	//后续处理,将返回的result[]中的String保存到数据库中,供下载时使用
}

4. 前端下载文件

使用ResponseEntity来返回文件流,ResponseEntity 对象表示响应体,它是最终返回给浏览器的对象,我们可以通过设置ResponseEntity对象来改变最终返回浏览的数据内容

ResponseEntity与@ResponseBody的区别:

  • @ResponseBody可以直接返回Json结果,
  • ResponseEntity不仅可以返回json结果,还可以定义返回的HttpHeaders和HttpStatus
  • ResponseEntity的优先级高于@ResponseBody。在不是ResponseEntity的情况下才去检查有没有@ResponseBody注解。如果响应类型是ResponseEntity可以不写@ResponseBody注解,写了也没有关系。

注意:这里我们泛型为byte数组,表示本次响应时以字节数组的方式进行响应,浏览器会弹出一个下载窗口

@RequestMapping("/download")
public ResponseEntity<byte[]> download(String groupName, String remoteFilePath) {
	//从FastDFS中获取到要下载的文件,使用的是2.4下载中的方法2
    byte[] buffFile = FastDFSUtils.download(groupName, remoteFilePath);
    //创建Http的响应头文件对象
    HttpHeaders headers = new HttpHeaders();
    //设置响应头中的响应类型为文件类型,这样浏览才会弹出下载窗口
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    //设置被下载的文件的大小,否则浏览器不会显示下载进度
    headers.setContentLength(creditorInfo.getFileSize());
    //指定文件下载时的默认文件名称,第一个参数内容固定
    headers.setContentDispositionFormData("attachment", creditorInfo.getOldFileName());

	//创建一个ResponseEntity对象,构造方法的参数:
	//第一个参数:响应的字节数组
	//第二个参数:Http响应头文件对象,设置响应的头信息
	//第三个参数:响应的状态码,是常量,HttpStatus.OK 表示 200
    ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(buffFile, headers, HttpStatus.OK);

    return responseEntity;
}

5. 删除文件简介

删除FastDFS和清除数据库,所以我们将这些业务都放在service中进行事务的处理

要先更新数据库,如果更新成功,再删除FastDFS中的文件