如何在fileupload struts2中删除.tmp文件 [英] How to delete .tmp file in fileupload struts2

查看:397
本文介绍了如何在fileupload struts2中删除.tmp文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 strtus-2.3.15.3 中使用了 file-upload (常见文件副本)。
我的 .jsp 中有一个表单,其中多个字段包含许多diff类型(textfield,textarea,hidden,file),包括 FILE 和明显的 SUBMIT

I have used file-upload (common fileuplod) in strtus-2.3.15.3 . There is one Form in my .jsp with multiple field with many diff type(textfield,textarea,hidden,file) including FILE and obvious SUBMIT.

当我通过选择一个文件提交表格并输入一些文字时在所有其他字段中,它在提及临时文件夹中生成 .tmp 文件。将文件上传到myfolder后,只有 .tmp 与文件字段相关的文件将被删除,但其余的 .tmp ( (1kb大小)文件正在重新映射为它。

When i submit form by selecting one file and enter some text in all other field its generated .tmp file in mention temp folder . Only .tmp file related to file field is going to delete after uploading my file to myfolder but rest of .tmp(with 1kb size) file is remaing as its .

List items = upload.parseRequest(servletRequest); 

以下代码中的这一行生成 .tmp 所有具有某些值的字段的文件(如果未在文本字段中输入任何文本,则不生成)。

This line in below code generate .tmp file for all field which have some value (if you do not enter any text in text field it not generated) .

MonitoredMultiPartRequest.java

public void parse(HttpServletRequest servletRequest, String saveDir)
            throws IOException
    {

        System.setProperty("java.io.tmpdir", "D:\\ankit");

        UploadListener listener = new UploadListener(servletRequest);
        // Create a factory for disk-based file items
        FileItemFactory factory = new MonitoredDiskFileItemFactory(listener);
        // Create a new file upload handler
        ServletFileUpload upload = new ServletFileUpload(factory);

    }

MonitoredDiskFileItemFactory

public class MonitoredDiskFileItemFactory extends DiskFileItemFactory
{
    HttpServletRequest request;

    public MonitoredDiskFileItemFactory(OutputStreamListener listener, HttpServletRequest request)
    {
        this.listener = null;
        this.listener = listener;
        this.request = request;
        setTrackers();
    }

    public void setTrackers()
    {
        FileCleaningTracker fileCleaningTracker = FileCleanerCleanup.getFileCleaningTracker(request.getServletContext());
        File repository = new File(System.getProperty("java.io.tmpdir"));
        DiskFileItemFactory factory = new DiskFileItemFactory(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD, repository);
        factory.setFileCleaningTracker(fileCleaningTracker);
        super.setFileCleaningTracker(fileCleaningTracker);
        super.setRepository(repository);
    }

    public MonitoredDiskFileItemFactory(int sizeThreshold, File repository, OutputStreamListener listener)
    {
        super(sizeThreshold, repository);
        this.listener = null;
        this.listener = listener;
    }

    public FileItem createItem(String fieldName, String contentType, boolean isFormField, String fileName)
    {
        MonitoredDiskFileItem result = new MonitoredDiskFileItem(fieldName, contentType, isFormField, fileName, getSizeThreshold(), getRepository(), listener);
        FileCleaningTracker tracker = getFileCleaningTracker();
        if (tracker != null)
        {
            tracker.track(result.getTempFileOfDistFileItem(), result);
        }

        return result;
    }

    private OutputStreamListener listener;
}

MonitoredDiskFileItem

public class MonitoredDiskFileItem extends DiskFileItem
{

    public MonitoredDiskFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository, OutputStreamListener listener)
    {
        super(fieldName, contentType, isFormField, fileName, sizeThreshold, repository);
        mos = null;
        this.listener = listener;
    }

    public OutputStream getOutputStream()
            throws IOException
    {
        if (mos == null)
            mos = new MonitoredOutputStream(super.getOutputStream(), listener);
        return mos;
    }

    public File getTempFileOfDistFileItem()
    {
        return super.getTempFile();
    }

    private MonitoredOutputStream mos;
    private OutputStreamListener listener;
}

UploadListener

public class UploadListener implements OutputStreamListener, Serializable
{
    private static final long serialVersionUID = 1L;
    private int totalToRead = 0;
    private int totalBytesRead = 0;
    private int percentDone = 0;
    private int previou_percentDone = 0;
    private long uploadspeed = 0;
    private long starttime;
    private long stTime, EndTime;
    HttpSession session;
    private int count = 0;

    public UploadListener(HttpServletRequest request)
    {
        totalToRead = request.getContentLength();
        session = request.getSession();
    }

    public void start()
    {
        session.setAttribute("percentageDone", 0);
        session.setAttribute("speed", 0);
        starttime = System.currentTimeMillis();
        stTime = starttime;

    }

    public String getMessage()
    {
        return "" + totalBytesRead + " bytes have been read (" + percentDone + "% done)  ";
    }

    public void bytesRead(int bytesRead)
    {
        totalBytesRead = totalBytesRead + bytesRead;

        if (100.00 * totalBytesRead > totalToRead)
        {
            previou_percentDone = percentDone;
            percentDone = (int) Math.round(100.00 * totalBytesRead / totalToRead);
            if (previou_percentDone < percentDone)
            {
                long speed = 0;
                try
                {
                    double TimediffInSecond = (System.currentTimeMillis() - starttime) / 1000;
                    if (TimediffInSecond > 0)
                        speed = Math.round(((totalBytesRead) / TimediffInSecond) / 1048576);
                    else
                        speed = totalBytesRead / 1048576;

                }
                catch (Exception e)
                {
                    System.err.println(e.getMessage());
                }
            }
        }


    }

    public void done()
    {
        EndTime = System.currentTimeMillis();
        session.setAttribute("percentageDone", 100);
        session.setAttribute("speed", 100);
    }

    @Override
    public void error(String message)
    {
        // System.out.println(message);
    }

    public long getUploadspeed()
    {
        return uploadspeed;
    }

    public void setUploadspeed(long uploadspeed)
    {
        this.uploadspeed = uploadspeed;
    }

}

编辑

1>为什么这个 .tmp 文件为字段生成(textarea,hidden,textfield)。
我们如何防止这种情况发生?

1> Why this .tmp file is generated for fields (textarea ,hidden,textfield) . How can we prevent this ?

2>我想停止为所有字段生成 .tmp 文件,除非类型='file'(文件字段)。

2> i want to stop generating .tmp file for all field except where type='file'(file field) .

3>否则,如何删除所有 .tmp 档案?

3> Otherwise, how can i delete this all .tmp file ?

推荐答案

你不需要Commons库,也不需要Servlet。

You don't need Commons libraries for this, nor a Servlet.

您正在使用Struts2,因此请勿重新发明轮子并使用操作拦截器

You are using Struts2, so don't reinvent the wheel and use Actions and Interceptors.

您可以在这个详尽的答案中找到使用Struts2上传多个文件的代码,并通过在另一个答案中创建自定义对象

You can find the code to upload multiple files with Struts2 in this exhaustive answer , and a little improvement by creating a custom object in this other answer.

我觉得需要链接在讨论时, BalusC的这个很好的答案也是如此fileUpload通过Servlet。

I feel the need to link this nice answer from BalusC too, when talking about fileUpload through Servlet.

让我们来讨论你的具体问题:你使用的是 MonitoredDiskFileItemFactory ,(你没有指定在t上增长的众多实现中的哪一个他是网络,但它可能是 - >)标准的子类 org.apache.commons.fileupload.disk.DiskFileItemFactory

Let's come to your specific question: you are using a MonitoredDiskFileItemFactory, (you didn't specified which of the many implementations growing on the web, but it is likely that it is ->) a Subclass of the standard org.apache.commons.fileupload.disk.DiskFileItemFactory.

在JavaDoc中,很好地解释了:

In the JavaDoc it is well explained that:


此实现创建 FileItem 实例
内容保留在内存中
,对于较小的项目,或保存在
磁盘上的临时文件
,对于较大的项目。 大小阈值,超过其内容将
存储在磁盘上,是可配置的
,以及将创建
临时文件的目录。

This implementation creates FileItem instances which keep their content either in memory, for smaller items, or in a temporary file on disk, for larger items. The size threshold, above which content will be stored on disk, is configurable, as is the directory in which temporary files will be created.

如果没有另外配置,默认配置值为
如下:

If not otherwise configured, the default configuration values are as follows:


  • 大小阈值是10KB。

  • 存储库是系统默认临时目录,由
    System.getProperty(java.io.tmpdir)

  • Size threshold is 10KB.
  • Repository is the system default temp directory, as returned by System.getProperty("java.io.tmpdir").

注意:文件是在具有可预测名称的系统默认临时目录中创建的。这意味着
,对该目录具有写访问权限的本地攻击者可以执行
a TOUTOC 攻击,以使用$ b $文件替换任何上传的文件b攻击者的选择。这意味着将取决于如何使用
上传文件但可能很重要。在具有本地不受信任的用户的环境中使用此
实现时,
setRepository(File)必须用于配置存储库位置
这不是公开可写的。在Servlet容器中,可以使用ServletContext属性
javax.servlet.context.tempdir 标识的位置

NOTE: Files are created in the system default temp directory with predictable names. This means that a local attacker with write access to that directory can perform a TOUTOC attack to replace any uploaded file with a file of the attackers choice. The implications of this will depend on how the uploaded file is used but could be significant. When using this implementation in an environment with local, untrusted users, setRepository(File) MUST be used to configure a repository location that is not publicly writable. In a Servlet container the location identified by the ServletContext attribute javax.servlet.context.tempdir may be used.

为文件项创建的临时文件应在以后删除
。最好的方法是使用 FileCleaningTracker
,你可以在 DiskFileItemFactory 上设置。但是,如果您使用
这样的跟踪器,则必须考虑以下事项:临时文件
会在不再需要时立即自动删除。 (更准确地说,
,当相应的File实例是垃圾
时收集。)这是由所谓的收割者线程完成的,当加载类FileCleaner时,
自动启动。例如,如果你的web
应用程序结束,那么终止该线程可能有
。请参阅commons-fileupload用户
指南中的资源清理部分。

Temporary files, which are created for file items, should be deleted later on. The best way to do this is using a FileCleaningTracker, which you can set on the DiskFileItemFactory. However, if you do use such a tracker, then you must consider the following: Temporary files are automatically deleted as soon as they are no longer needed. (More precisely, when the corresponding instance of File is garbage collected.) This is done by the so-called reaper thread, which is started automatically when the class FileCleaner is loaded. It might make sense to terminate that thread, for example, if your web application ends. See the section on "Resource cleanup" in the users guide of commons-fileupload.

From < a href =http://commons.apache.org/proper/commons-fileupload/using.html =nofollow noreferrer> Commons FileUpload Documantation


资源清理



此部分仅适用于您使用 DiskFileItem 。在其他
字中,如果您上传的文件在处理之前写入临时
文件,则适用。

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.

此类临时文件会自动删除,如果它们不再使用
(更准确地说,如果 java.io.File 的相应实例是
垃圾收集。这是通过以下方式静默完成的
org.apache.commons.io.FileCleaner 类,它启动一个收割者线程。

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.

如果不再需要,则应该停止这个收割者线程。在
servlet环境中,这是通过使用特殊的servlet上下文
监听器来完成的,名为 FileCleanerCleanup 。为此,请在您的web.xml后面添加
之类的部分:

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:

<web-app>
  ...
  <listener>
    <listener-class>
      org.apache.commons.fileupload.servlet.FileCleanerCleanup
    </listener-class>
  </listener>
  ...
</web-app>

创建DiskFileItemFactory

Creating a DiskFileItemFactory

FileCleanerCleanup 提供
的实例 org.apache.commons.io.FileCleaningTracker 。创建
org.apache.commons.fileupload.disk.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);
    DiskFileItemFactory factory
          = new DiskFileItemFactory(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD,
                                      repository);
    factory.setFileCleaningTracker(fileCleaningTracker);
    return factory;
}

禁用临时文件清理

Disabling cleanup of temporary files

要禁用对临时文件的跟踪,您可以将
FileCleaningTracker 设置为null。因此,创建的文件将不再跟踪
。特别是,它们将不再自动删除

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.

然后你可以:


  1. 设置更高的threeshold,以保留所有内存而不是使用临时文件,或

  2. 遵循Apache指南以便在不再需要时正确删除临时文件

  1. set an higher threeshold, to keep everything in memory instead that using temporary files, or
  2. follow Apache guidelines to properly wipe temporary files when they're not needed anymore.

这篇关于如何在fileupload struts2中删除.tmp文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆