Multipartfile转File?File转MultipartFile?可千万别转晕了。

题图:from Google

1. MultipartFile类型转File类型

想要将MultipartFile类型转为File类型可以使用MultipartFile提供的方法:
void MultipartFile.transferTo(File dest) throws IOException, IllegalStateException

1
2
3
4
5
6
File destFile = new File("tmp/source/destFile");
if (!fileSourcePath.exists()) {
fileSourcePath.mkdirs();
}
// 将MultipartFile存到临时文件中
mulFileSource.transferTo(destFile);

2. File类型转Multipartfile

MultipartFile接口有两个常用实现类,MockMultipartFile和CommonsMultipartFile。

  • 使用MockMultipartFile
    看名字就知道MockMultipartFile主要用于测试用途,但是相对CommonsMultipartFile来说,创建相当简便。

    1
    2
    3
    4
    5
    6
    7
    File file = new File("/Users/coderec/Desktop/haha.jpg");
    MultipartFile mulFile = new MockMultipartFile(
    "haha.jpg", //文件名
    "haha.jpg", //originalName 相当于上传文件在客户机上的文件名
    ContentType.APPLICATION_OCTET_STREAM.toString(), //文件类型
    new FileInputStream(file) //文件流
    );
  • 使用CommonsMultipartFile
    与MockMultipartFile相比,CommonsMultipartFile仅仅有一个构造方法:
    CommonsMultipartFile(FileItem fileItem)
    因此,若要使用CommonsMultipartFile来创建MultipartFile就一定要使用FileItem。通过FileItem将File转化为MultipartFile的过程如下伪代码所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    File file = new File("temp/fileItem/haha.jpg");
    if (!file.exists()) {
    file.mkdirs();
    }
    // 创建fileItem,具体方法参见第三节
    FileItem fileItem = new ...;
    // 将File内容写入fileItem,使用org.apache.commons.io.IOUtils
    IOUtils.copy(new FileInputStream(file), fileItem.getOutputStream());
    // 创建multipartfile
    MultipartFile multipartFile = new CommonsMultipartFile(fileItem);

3. 如何创建FileItem?

FileItem接口只有一个实现类:DiskFileItem

  • 直接使用DiskFileItem创建

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // 创建fileItem
    FileItem fileItem = new DiskFileItem(
    "file", // 表单参数名
    ContentType.APPLICATION_OCTET_STREAM.toString(), // 文件类型
    false, // 是否为表单格式
    RandomKeyUtils.genRandomKey() + ".jpg", // 文件名
    10240, // 超过多少byte存在磁盘上
    new file("tmp/fileItem/") // 文件存储位置
    );
  • 使用DiskFileItemFactory创建

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // 小于5M文件都在内存中,否则存入硬盘
    final int tmpFileSize = 5242880;
    // 设置临时文件大小以及临时文件存储路径
    DiskFileItemFactory fileItemFactory = new DiskFileItemFactory(tmpFileSize, new file("tmp/fileItem/"));
    // 创建fileItem
    FileItem fileItem = fileItemFactory.createItem(
    "file", // 表单参数名
    ContentType.APPLICATION_OCTET_STREAM.toString(), // 文件类型
    false, // 是否为表单格式
    RandomKeyUtils.genRandomKey() + ".jpg" // 文件名
    );

4. DiskFileItem产生的临时文件处理

  • 使用内存存储,不写入硬盘
    在创建FileItem时,可以设定一个较大的文件大小,使文件不被写入硬盘,就不会产生临时文件的问题。不过这不是一个正确的解决问题的方式。而且,也会受到内存大小限制。
  • 使用FileCleaningTracker
    在使用DiskFileItemFactory时,应该会发现其有一个void setFileCleaningTracker(FileCleaningTracker pTracker)方法,此方法就是为临时文件设置监听线程,一旦发现临时文件被垃圾回收,就会清除临时文件。
    我们可以通过FileCleanerCleanup监听器以及ServletContext获得监听线程FileCleaningTracker。

为FileItem设置监听的过程如下:

1
2
3
4
5
FileCleaningTracker fileCleaningTracker
= FileCleanerCleanup.getFileCleaningTracker(servletContext);
DiskFileItemFactory factory
= new DiskFileItemFactory(10240, File("tmp/fileItem/");
factory.setFileCleaningTracker(fileCleaningTracker);

在不需要监听线程FileCleaningTracker时,应该将其停止。可以在web.xml中进行如下配置:

1
2
3
4
5
6
7
8
9
<web-app>
...
<listener>
<listener-class>
org.apache.commons.fileupload.servlet.FileCleanerCleanup
</listener-class>
</listener>
...
</web-app>
  • 获取ServletContext方法
    1. 普通Servlet中
      使用HttpServletRequest
      request.getSession().getServletContext()
    2. SpringMVC的Controller中
      使用SpringMVC提供的方法
      1
      2
      WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
      ServletContext servletContext = webApplicationContext.getServletContext();

MultipartFile的使用小结的更多相关文章

  1. 180730-Spring之RequestBody的使用姿势小结

    Spring之RequestBody的使用姿势小结 SpringMVC中处理请求参数有好几种不同的方式,如我们常见的下面几种 根据 HttpServletRequest 对象获取 根据 @PathVa ...

  2. 导入解析excel小结

    导入解析excel小结 控制器例子:

  3. 阿里出品Excel工具EasyExcel使用小结

    前提 笔者做小数据和零号提数工具人已经有一段时间,服务的对象是运营和商务的大佬,一般要求导出的数据是Excel文件,考虑到初创团队机器资源十分有限的前提下,选用了阿里出品的Excel工具EasyExc ...

  4. 从零开始编写自己的C#框架(26)——小结

    一直想写个总结,不过实在太忙了,所以一直拖啊拖啊,拖到现在,不过也好,有了这段时间的沉淀,发现自己又有了小小的进步.哈哈...... 原想框架开发的相关开发步骤.文档.代码.功能.部署等都简单的讲过了 ...

  5. Python自然语言处理工具小结

    Python自然语言处理工具小结 作者:白宁超 2016年11月21日21:45:26 目录 [Python NLP]干货!详述Python NLTK下如何使用stanford NLP工具包(1) [ ...

  6. java单向加密算法小结(2)--MD5哈希算法

    上一篇文章整理了Base64算法的相关知识,严格来说,Base64只能算是一种编码方式而非加密算法,这一篇要说的MD5,其实也不算是加密算法,而是一种哈希算法,即将目标文本转化为固定长度,不可逆的字符 ...

  7. iOS--->微信支付小结

    iOS--->微信支付小结 说起支付,除了支付宝支付之外,微信支付也是我们三方支付中最重要的方式之一,承接上面总结的支付宝,接下来把微信支付也总结了一下 ***那么首先还是由公司去创建并申请使用 ...

  8. iOS 之UITextFiled/UITextView小结

    一:编辑被键盘遮挡的问题 参考自:http://blog.csdn.net/windkisshao/article/details/21398521 1.自定方法 ,用于移动视图 -(void)mov ...

  9. K近邻法(KNN)原理小结

    K近邻法(k-nearst neighbors,KNN)是一种很基本的机器学习方法了,在我们平常的生活中也会不自主的应用.比如,我们判断一个人的人品,只需要观察他来往最密切的几个人的人品好坏就可以得出 ...

随机推荐

  1. Spring 通知

    1. AspectJ 支持 5 种类型的通知注解:  @Before: 前置通知, 在方法执行之前执行 @After: 后置通知, 在方法执行之后执行 @AfterRunning: 返回通知, 在方法 ...

  2. Oracle电子商务套件版本12.1.3自述文件 (Doc ID 1534411.1)

    文档内容 用途 适用范围 详细信息   应用版本更新包   更新后的步骤   包含的修补程序列表   变更记录   文档可访问性 参考 适用于: Oracle Applications DBA - 版 ...

  3. ASP.NET 邮件发送

    ASP.NET 邮件发送用NET的MAIL类即可实现. 邮件发时,为不影响进程,所以采用多线程实现比较好. /// <summary> /// 多线程邮件发送 多线程需注意不要引用到外部方 ...

  4. cesium编程中级(一)添加示例到Sandcastle

    cesium编程中级(一)添加示例到Sandcastle 添加示例到Sandcastle在cesium编程入门(七)3D Tiles,模型旋转中提到过,这里是一份完整的说明 创建例子 开启node服务 ...

  5. java.lang.NoSuchMethodError: javax.servlet.ServletContext.getContextPath()Ljava/lang/String;

    问题描述:在eclipse3.7中启动tomcat6时一直出现这个错误, java.lang.NoSuchMethodError: javax.servlet.ServletContext.getCo ...

  6. Python 错误和异常小结

    1.Python异常类 Python是面向对象语言,所以程序抛出的异常也是类.常见的Python异常有以下几个,大家只要大致扫一眼,有个映像,等到编程的时候,相信大家肯定会不只一次跟他们照面(除非你不 ...

  7. GO学习笔记 - 用defer来实现try{}finally{}

    在Delphi中,try{}finally{}语句非常有用,对于一定要最终执行的语句,我们放到finally,从而保证程序顺利执行!在GO语言中没有try{}finally{}语句,但是GO语言用另外 ...

  8. Net Manager测试连接测试没有成功,用户权限问题,以管理员身份运行后测试成功

    Net Manager测试连接测试没有成功,截图如下:

  9. 关于gcd和exgcd的一点心得,保证看不懂(滑稽)

    网上看了半天……还是没把欧几里得算法和扩展欧几里得算法给弄明白…… 然后想了想自己写一篇文章好了…… 参考文献:https://www.cnblogs.com/hadilo/p/5914302.htm ...

  10. LG的nexus5(32GB版本 - 821)-TOT-底包 可用于救砖!

    LG的nexus5(32GB版本 - 821)-TOT-底包 底层修复效果完美,通过LGflashTool1.8直接刷进去就行~ 底包下载: https://pan.baidu.com/s/1Z5WD ...