commons-fileupload源码学习心得
commons-fileupload依赖于commons-io包。
commons-fileupload的使用方法:
1.创建一个文件项目工厂类DiskFileItemFactory。
DiskFileItemFactory有俩个构造方法:
DiskFileItemFactory() 其中sizeThreshold是默认值10kB, 文件大小不超过这个值将内容保存在内存,超过这个值会把文件保存到临时目录下,可用System.getProperty("java.io.tmpdir")获取;
DiskFileItemFactory(int sizeThreshold, File repository) 可以指定sizeThreshold, 和文件保存到磁盘的路径。
DiskFileItemFactory有一个属性FileCleaningTracker,设置这个属性可以用来追踪删除临时文件。当这个临时文件不再被使用时将会被立即删除,更精确的说是这个文件对象被垃圾收集器回收时,FileCleaningTracker将启动收获者线程(reaper thread)自动删除这个临时文件。FileCleaningTracker是commons-io包的工具类。
FileCleaningTracker fileCleaningTracker = FileCleanerCleanup.getFileCleaningTracker(servletcontext);
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setFileCleaningTracker(fileCleaningTracker);
ServletContext获取的几种方法:
Javax.servlet.http.HttpSession.getServletContext();
Javax.servlet.jsp.PageContext.getServletContext();
Javax.servlet.ServletConfig.getServletContext();
2.创建一个文件处理类ServletFileUpload。
ServletFileUpload解析上传请求request的信息,封装到FileItem类中,我们通过FileItem可以获取文件的名称、大小、文件流等信息。
ServletFileUpload sfu = new ServletFileUpload(factory);
ServletFileUpload可以设置:
headerEncoding 读取请求头信息时使用的编码
sizeMax 单次请求所能上传的文件总大小的最大size,默认是-1,不限制大小
fileSizeMax 单次请求所能上传的单个文件最大size,默认是-1,不限制大小
List<FileItem> items = sfu.parseRequest(req);
ServletFileUpload对上传请求信息的解析流程:
文件上传的html代码如下:
<form action="http://server.dom/cgi/handle" enctype="multipart/form-data" method=POST>
What is your name? <input type=text name=submitter/>
What files are you sending? <input type=file name=pics/>
</form>
浏览器传送的数据格式如下:
Content-type: multipart/form-data, boundary=AaB03x --AaB03x content-disposition: form-data; name="field1" Joe Blow --AaB03x content-disposition: form-data; name="pics"; filename="file1.txt" Content-Type: text/plain ... contents of file1.txt ... --AaB03x--
数据的每段格式如下:
multipart-body := preamble 1*encapsulation close-delimiter epilogue
encapsulation := delimiter body CRLF
delimiter := "--" boundary CRLF
close-delimiter := "--" boundary "--"
preamble := <ignore>
epilogue := <ignore>
body := header-part CRLF body-part
header-part := 1*header CRLF
header := header-name ":" header-value
header-name := <printable ascii characters except ":">
header-value := <any ascii characters except CR & LF>
body-data := <arbitrary data>
先通过request获取content-type,解析content-type获取每段的边界分隔字符串boundary。
然后根据boundary获取header-part的header参数的值和body-data的值组装到FileItem中。
FileCleaningTracker的使用方法:
在web.xml配置如下监听器:
<listener>
<listener-class>org.apache.commons.fileupload.servlet.FileCleanerCleanup</listener-class>
</listener>
FileCleanerCleanup实现了ServletContextListener监听类,在web启动时调用ServletContext.setAttribute()方法设置了一个全局共享的FileCleaningTracker对象。
在 Servlet API 中有一个 ServletContextListener 接口,它能够监听 ServletContext 对象的生命周期,实际上就是监听Web应用的生命周期。
当Servlet 容器启动或终止Web 应用时,会触发ServletContextEvent 事件,该事件由 ServletContextListener 来处理。在 ServletContextListener 接口中定义了处理 ServletContextEvent 事件的两个方法:public void contextInitialized(ServletContextEvent sce)和public void contextDestroyed(ServletContextEvent sce)。
ServletFileUpload在解析request,封装FileItem时,会将创建的临时文件添加到FileCleaningTracker的追踪容器trackers(一个Vector的集合)里,然后后台一直默默执行的收获者线程Reaper Thread会自动删除这个临时文件。
Tracker类继承了PhantomReference虚引用,虚引用在系统垃圾回收器开始回收对象时 , 将直接调用 finalize() 方法 , 但不会立即将其加入回收队列 . 只有在真正对象被 GC 清除时 , 才会将其加入 Reference 队列中去。
问题是:我没弄明白这个Reaper Thread多久会执行一次?什么条件会触发它?是否是在垃圾回收的时候才触发,哪位高手指点一二,多谢!!!
Reaper线程的定义如下:
/**
* The reaper thread.
*/
private final class Reaper extends Thread {
/** Construct a new Reaper */
Reaper() {
super("File Reaper");
setPriority(Thread.MAX_PRIORITY);
setDaemon(true);
} /**
* Run the reaper thread that will delete files as their associated
* marker objects are reclaimed by the garbage collector.
*/
public void run() {
// thread exits when exitWhenFinished is true and there are no more tracked objects
while (exitWhenFinished == false || trackers.size() > 0) {
Tracker tracker = null;
try {
// Wait for a tracker to remove.
tracker = (Tracker) q.remove();
} catch (Exception e) {
continue;
}
if (tracker != null) {
tracker.delete();
tracker.clear(); //此处的作用不是很明白??
trackers.remove(tracker); //此处明明移除了已删除的临时文件,但是我调用getTrackCount()方法查看等待删除的临时文件的个数没变,为什么呢?
}
}
}
}
commons-fileupload源码学习心得的更多相关文章
- Dapper源码学习和源码修改(下篇)
目录: Dapper源码学习和源码修改(上篇主要讲解入参解析) Dapper源码学习和源码修改(下篇主要讲解出参解析) 继上篇讲了下自己学习Dapper的心得之后,下篇也随之而来,上篇主要讲的入参解析 ...
- Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件
写在前面 从大四实习至今已一年有余,作为一个程序员,一直没有用心去记录自己工作中遇到的问题,甚是惭愧,打算从今日起开始养成写博客的习惯.作为一名java开发人员,Spring是永远绕不过的话题,它的设 ...
- Tomcat源码学习
Tomcat源码学习(一) 转自:http://carllgc.blog.ccidnet.com/blog-htm-do-showone-uid-4092-type-blog-itemid-26309 ...
- Hadoop源码学习笔记(2) ——进入main函数打印包信息
Hadoop源码学习笔记(2) ——进入main函数打印包信息 找到了main函数,也建立了快速启动的方法,然后我们就进去看一看. 进入NameNode和DataNode的主函数后,发现形式差不多: ...
- 【目录】Spring 源码学习
[目录]Spring 源码学习 jwfy 关注 2018.01.31 19:57* 字数 896 阅读 152评论 0喜欢 9 用来记录自己学习spring源码的一些心得和体会以及相关功能的实现原理, ...
- JDK1.8源码分析01之学习建议(可以延伸其他源码学习)
序言:目前有个计划就是准备看一下源码,来提升自己的技术实力.同时现在好多面试官都喜欢问源码,问你是否读过JDK源码等等? 针对如何阅读源码,也请教了我的老师.下面就先来看看老师的回答,也许会有帮助呢. ...
- mybatis源码学习(一) 原生mybatis源码学习
最近这一周,主要在学习mybatis相关的源码,所以记录一下吧,算是一点学习心得 个人觉得,mybatis的源码,大致可以分为两部分,一是原生的mybatis,二是和spring整合之后的mybati ...
- Spring5.0源码学习系列之Spring AOP简述
前言介绍 附录:Spring源码学习专栏 在前面章节的学习中,我们对Spring框架的IOC实现源码有了一定的了解,接着本文继续学习Springframework一个核心的技术点AOP技术. 在学习S ...
- Java集合专题总结(1):HashMap 和 HashTable 源码学习和面试总结
2017年的秋招彻底结束了,感觉Java上面的最常见的集合相关的问题就是hash--系列和一些常用并发集合和队列,堆等结合算法一起考察,不完全统计,本人经历:先后百度.唯品会.58同城.新浪微博.趣分 ...
随机推荐
- hadoop的wordcount例子运行
可以通过一个简单的例子来说明MapReduce到底是什么: 我们要统计一个大文件中的各个单词出现的次数.由于文件太大.我们把这个文件切分成如果小文件,然后安排多个人去统计.这个过程就是”Map”.然后 ...
- -_-#【减少 DOM 访问】“离线”更新节点,再将它们添加到树中
Minimize DOM Access javascript 之 DOM 优化 <!DOCTYPE html> <html> <head> <meta cha ...
- java 页面url传值中文乱码的解决方法
parent.window.location.href 和 iframe中src的乱码问题.要在这两个url地址中传中文,必须加编码,然后再解码.编码:encodeURI(encodeURI(&quo ...
- 浏览器加载和渲染html的顺序-css渲染效率的探究
1.浏览器加载和渲染html的顺序1.IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的.2.在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联的元素都 ...
- 延期(deferred)的承诺(promise) — jq异步编程浅析
引子 相信各位developers对js中的异步概念不会陌生,异步操作后的逻辑由回调函数来执行,回调函数(callback function)顾名思义就是“回头调用的函数”,函数体事先已定义好,在未来 ...
- 对ASP.NET程序员非常有用的85个工具
介绍 这篇文章列出了针对 ASP.NET 开发人员的有用工具. 工具 1. Visual Studio Visual Studio Productivity Power tool:Visual Stu ...
- nmon for linux
nmon(为Nigel's performance Monitor的简写) for linux工具是 IBM开源的在POWER, x86, x86_64, Mainframe & now AR ...
- [原]loadrunner中数据库数据参数化
作者:liuheng123456 发表于2013-11-25 14:11:10 原文链接 阅读:228 评论:0 查看评论
- 易元平台使用-MVC体会
M:服务-提供数据 V:freemaker-提供显示方式 C:控制器-控制显示方式
- 第二步 在D2RQ平台上配置jena环境
第二步 在D2RQ平台上配置jena环境 2013年10月16日 9:48:53 搞了这么长时间语义,只用过protege这样的工具,一直没有落实到实际代码上.jena也看过好久了,总认为是hp公司的 ...