文件上传组件使用说明

A file upload request comprises an ordered list of items that are encoded according to RFC 1867 , "Form-based File Upload in HTML". FileUpload can parse such a request and provide your application with a list of the individual uploaded items. Each such item implements the FileItem interface, regardless of its underlying implementation.

一个文件上传请求由一个根据RFC1867,“HTML中基于表单的文件上传",编码的有序列表组成。FileUpload能够解析这样的一个请求并且为你的应用程序提供一个由单个的已经传上来的项目组成的列表。每一个这样的项目都实现了FileItem接口,无论其底层实现细节。

This page describes the traditional API of the commons fileupload library. The traditional API is a convenient approach. However, for ultimate performance, you might prefer the faster Streaming API .

本页描述组建库的传统API,这是便捷的方法。然而,为了极速的性能,你应当选择更快的Streaming API。

Each file item has a number of properties that might be of interest for your application. For example, every item has a name and a content type, and can provide an InputStream to access its data. On the other hand, you may need to process items differently, depending upon whether the item is a regular form field - that is, the data came from an ordinary text box or similar HTML field - or an uploaded file. The FileItem interface provides the methods to make such a determination, and to access the data in the most appropriate manner.

每一个文件项都有许多你的应用也许会感兴趣的属性。例如,每一个项目都有一个名字和内容类型,并且能够提供一个InputStream对象来访问其数据。另一方面,你也可以用不同的方式处理项目,取决于该项目是否为一个普通的表单域-即,数据是来自普通的文本框或者类似的HTML域,还是一个传上来的文件。FileItem接口提供作出此类判断和以最合适的方式访问其数据的方法。

FileUpload creates new file items using a FileItemFactory. This is what gives FileUpload most of its flexibility. The factory has ultimate control over how each item is created. The factory implementation that currently ships with FileUpload stores the item's data in memory or on disk, depending on the size of the item (i.e. bytes of data). However, this behavior can be customized to suit your application.

FileUpload使用FileItemFactory来创建新的文件项目。这是FileUpload所具有的灵活性的关键。该工厂类具有如何创建每个项的最终控制权。与FileUpload组建一同发布的该工厂类的实现根据该项目的大小(即数据的字节数)将具体项目的数据存储于内存或硬盘。然而,本行为也可被定制化以适合你的应用。

Parsing the request(解析请求)

Before you can work with the uploaded items, of course, you need to parse the request itself. Ensuring that the request is actually a file upload request is straightforward, but FileUpload makes it simplicity itself, by providing a static method to do just that.
在你能够使用上传来的项目之前,你理所应当地需要解析该请求本身。保证此请求确实是一个文件上传请求是直白的,但是FileUpload通过提供一个静态方法来完成它使其变得简单。

// Check that we have a file upload request
boolean isMultipart = ServletFileUpload.isMultipartContent(request);

Now we are ready to parse the request into its constituent items.
现在我们准备将该请求解析成构成项目。
The simplest usage scenario is the following:
最简单的使用场景如下:
* Uploaded items should be retained in memory as long as they are reasonably small.
只要他们足够小,上传的项目将被存在内存。
* Larger items should be written to a temporary file on disk.
更大的项目应当被写到硬盘中的临时文件。
* Very large upload requests should not be permitted.
非常大的上传请求不应当被允许。
* The built-in defaults for the maximum size of an item to be retained in memory, the maximum permitted size of an upload request, and the location of temporary files are acceptable.
关于一个项目的最大内存存储大小,最大允许上传请求大小和临时文件的存储路径的缺省值是可接受的。

Handling a request in this scenario couldn't be much simpler:
处理一个此类应用场景的请求不可能比如下代码更简单的了:

// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory();

// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);

// Parse the request
List /* FileItem */ items = upload.parseRequest(request);

That's all that's needed. Really!
这就是所需要的全部,真的!
The result of the parse is a List of file items, each of which implements the FileItem interface. Processing these items is discussed below.
解析的结果是一个文件项目的列表,每一个项目都实现了FileItem接口。下面将要处理这些项目。

Exercising more control(行使更多控制)

If your usage scenario is close to the simplest case, described above, but you need a little more control, you can easily customize the behavior of the upload handler or the file item factory or both. The following example shows several configuration options:
若你的使用场景类似于上述最简单的事例,但是你需要更多一点的控制,你可以定制上传处理器或文件项目工厂的行为甚或定制两者。以下代码示例展示了几种配置选项:

// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();

// Set factory constraints
factory.setSizeThreshold(yourMaxMemorySize);
factory.setRepository(yourTempDirectory);

// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);

// Set overall request size constraint
upload.setSizeMax(yourMaxRequestSize);

// Parse the request
List /* FileItem */ items = upload.parseRequest(request);

Of course, each of the configuration methods is independent of the others, but if you want to configure the factory all at once, you can do that with an alternative constructor, like this:
当然,每一个配置方法都独立于其它方法,但是,若你需要一次对项目工厂进行配置,你可以使用一个替代性的构建方法:

// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory(
yourMaxMemorySize, yourTempDirectory);

Should you need further control over the parsing of the request, such as storing the items elsewhere - for example, in a database - you will need to look into customizing FileUpload.
如果你需要对请求的解析进行进一步的控制,比如将项目存储于其它地方-例如,存到数据库中,你需要查阅定制化FileUpload.

Processing the uploaded items
处理上传项目
Once the parse has completed, you will have a List of file items that you need to process. In most cases, you will want to handle file uploads differently from regular form fields, so you might process the list like this:
一旦解析完成,你将得到一个待处理的文件项目的列表。在多数情况下,你将需要同普通表单域不一样的处理,所以你应像这样来处理这个列表:

// Process the uploaded items
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();

if (item.isFormField()) {
processFormField(item);
} else {
processUploadedFile(item);
}
}

For a regular form field, you will most likely be interested only in the name of the item, and its String value. As you might expect, accessing these is very simple.
对于一个常规的表单域,你最可能对该项的名字感兴趣和它的字符串值。如你所料,访问这些是非常简单的。

// Process a regular form field
if (item.isFormField()) {
String name = item.getFieldName();
String value = item.getString();
...
}

For a file upload, there are several different things you might want to know before you process the content. Here is an example of some of the methods you might be interested in.
对于一个文件上传,在你处理内容之前,有几个不同的东西需要知道。下列示例方法你也许会感兴趣。

// Process a file upload
if (!item.isFormField()) {
String fieldName = item.getFieldName();
String fileName = item.getName();
String contentType = item.getContentType();
boolean isInMemory = item.isInMemory();
long sizeInBytes = item.getSize();
...
}

With uploaded files, you generally will not want to access them via memory, unless they are small, or unless you have no other alternative. Rather, you will want to process the content as a stream, or write the entire file to its ultimate location. FileUpload provides simple means of accomplishing both of these.
对于上传的文件,你一般不会想通过内存来存取他们,除非他们非常小,或者你别无选择。你将需要将内容作为一个来处理,或者将整个文件写道它的最终位置。FileUpload提供了完成此两种情况的简单方法。

// Process a file upload
if (writeToFile) {
File uploadedFile = new File(...);
item.write(uploadedFile);
} else {
InputStream uploadedStream = item.getInputStream();
...
uploadedStream.close();
}

Note that, in the default implementation of FileUpload, write() will attempt to rename the file to the specified destination, if the data is already in a temporary file. Actually copying the data is only done if the the rename fails, for some reason, or if the data was in memory.
注意,在FileUpload的缺省实现里,write()将尝试重新命名文件到指定的位置,若数据已经在临时文件中。实际上,由于某种原因或者数据在内存中,只有在重新命名失败时才拷贝数据。
If you do need to access the uploaded data in memory, you need simply call the get() method to obtain the data as an array of bytes.
如果你需要访问上传于内存的数据,你只需要调用get()方法来获得字节数组类型的数据。

// Process a file upload in memory
byte[] data = item.get();
...

Resource cleanup
资源清理
This section applies only, if you are using the DiskFileItem . In other words, it applies, if your uploaded files are written to temporary files before processing them.
本部分只适用于使用DiskFileItem的时候。也就是说,它只适用于在处理之前,将上传文件写到临时文件中。

Such temporary files are deleted automatically, if they are no longer used (more precisely, if the corresponding instance of java.io.File is garbage collected. This is done silently by the org.apache.commons.io.FileCleaner class, which starts a reaper thread.
若不再被使用(更确切些,若相应的java.io.File实例被垃圾回收了),这些临时文件被自动删除。这由org.apache.commons.io.FileCleaner类,该类开启一个回收线程,悄悄地执行。

This reaper thread should be stopped, if it is no longer needed. In a servlet environment, this is done by using a special servlet context listener, called FileCleanerCleanup . To do so, add a section like the following to your web.xml:
这个回收线程将被关闭,如果不再需要。在一个servlet容器环境中,这些由一个特殊的被称为FileCleanerCleanup的servlet context listener监听器实现。为此,向你的web.xml文件加入如下配置段:
<web-app>
...
<listener>
<listener-class>
org.apache.commons.fileupload.servlet.FileCleanerCleanup
</listener-class>
</listener>
...
</web-app>

Creating a DiskFileItemFactory
创建工厂类DiskFileItemFactory

The FileCleanerCleanup provides an instance of org.apache.commons.io.FileCleaningTracker. This instance must be used when creating a org.apache.commons.fileupload.disk.DiskFileItemFactory. This should be done by calling a method like the following:

public static DiskFileItemFactory newDiskFileItemFactory(ServletContext context,
File repository) {
FileCleaningTracker fileCleaningTracker
= FileCleanerCleanup.getFileCleaningTracker(context);
return new DiskFileItemFactory(fileCleaningTracker,
DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD,
repository);
}

Disabling cleanup of temporary files
禁止清理临时文件
To disable tracking of temporary files, you may set the FileCleaningTracker to null. Consequently, created files will no longer be tracked. In particular, they will no longer be deleted automatically.
为了禁止跟踪哦临时文件,你可以设置FileCleaningTracker为空对象null。然后,创建的文件将不再被跟踪。特别地,他们不再被自动删除。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值