【问题标题】:Java Servlet JSP delete file using apache commons FileUploadJava Servlet JSP 使用 apache commons FileUpload 删除文件
【发布时间】:2013-01-01 15:34:18
【问题描述】:

我一直在寻找这个主题很长一段时间,并没有找到任何能够解决我的问题的东西..所以我求助于你!

我有一个 JSP,我在其中打开一个文件对话框来选择一个文件。以前,我使用它来将文件上传到指定目录(在我的代码中)。这工作正常。我现在尝试使用相同的代码删除相同的文件,方法是在适当的目录中选择它并将其传递给我在下面包含的 servlet。我正在使用 Apache Common FileUpload 库来执行此操作。

protected void doPost(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    // checks if the request actually contains upload file
    if (!ServletFileUpload.isMultipartContent(request)) {
        // if not, we stop here
        return;
    }

    // configures some settings
    DiskFileItemFactory factory = new DiskFileItemFactory();

    ServletFileUpload delete = new ServletFileUpload(factory);

    // constructs the directory path to delete file
    String deletePath = UPLOAD_DIRECTORY;

    // parses the request's content to extract file data
    List formItems = delete.parseRequest(request);
    Iterator iter = formItems.iterator();

    // iterates over form's fields
    while (iter.hasNext()) {
        FileItem item = (FileItem) iter.next();


        // processes only fields that are not form fields
        if (!item.isFormField()) {


            String fileName = new File(item.getName()).getName();
            String filePath = deletePath + File.separator + fileName;
            File storeFile = new File(filePath);

            //File storeFile = new File("C:\\temp\\discLogo.txt");

            // deletes the file on disk
            boolean erased = storeFile.delete();
            }
        }

UPLOAD_DIRECTORY 是我从上传 JSP 存储文件的位置。如果我用硬编码目录取消注释我为 storeFile 注释掉的行,删除方法工作正常,只要我最初在目录中选择一个不同的文件。这让我相信 HttpServletRequest 将文件保存在内存中的某个地方。

这是正确的吗?有什么办法可以释放它,以便我可以删除最初选择的文件?还是有更简单的方法来做到这一点?

谢谢!

【问题讨论】:

    标签: java jsp servlets


    【解决方案1】:

    你可以删除文件,因为平台无关的解决方案是这样的

    File deleteFile = new File(<file Path> ) ;
    // check if the file  present or not
    if( deleteFile.exists() )
    deleteFile.delete() ;
    

    注意,如果文件路径是目录,那么目录必须在删除之前为空。 UploadFileorDelete

    【讨论】:

      【解决方案2】:

      看起来我的问题出在我的 JSP 中。我最初有以下表格:

      <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
      pageEncoding="ISO-8859-1"%>
      <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
      <html>
      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
      <title>File Delete</title>
      </head>
      <body>
          <form method="post" action="DeleteServlet"
              enctype="multipart/form-data">
              Select file to delete: <input type="file" name="dataFile"
                  id="fileChooser" /><br />
              <br /> <input type="submit" value="Delete" />
          </form>
      </body>
      </html>
      

      我通过从表单中删除 encytype="multipart/form-data" 来更改此设置,然后能够使用 request.getParameter("dataFile") 获取文件名。

      【讨论】:

      • 这不是正确的解决方案。您应该在服务器端对文件名不感兴趣,而对文件内容感兴趣。到目前为止,您的代码只能在网络浏览器和网络服务器碰巧在同一台机器上运行的环境中工作(因为它们可以访问相同的本地磁盘文件系统)。这在现实世界中绝对不会发生,这正是 Apache Commons FileUpload 存在的原因。另见*.com/questions/81180/…
      【解决方案3】:

      File#delete() 将返回false 如果文件根本不存在(使用File#exists() 预先测试它),或者如果文件被另一个应用程序甚至您自己的代码打开而被锁定!

      如果此文件是由您自己的代码预先写入磁盘并保证不会在其他地方打开,那么您应该确保在写入文件内容后在finally 块中调用OutputStream#close()。这个问题表明你没有。如果您在写入文件后保持打开状态,则在重新启动服务器/JVM 之前无法将其删除。

      Apache Commons IO,作为 FileUpload 的依赖项,您应该已经拥有它,它带有方便的实用方法,可减少文件复制和关闭样板文件。

      InputStream input = item.getInputStream();
      OutputStream output = new FileOutputStream(storeFile);
      
      try {
          IOUtils.copy(input, output);
      } finally {
          IOUtils.closeQuietly(output);
          IOUtils.closeQuietly(input);
      }
      

      另见:

      【讨论】:

        【解决方案4】:

        上传文件的对象是什么?您要按内容检查所有文件吗?

        我想说更简单的方法是不上传整个文件。您要做的是调用一些代码 - JSP/Servlet - 作为参数传递文件的 ID(通常是 服务器内部的路径)并使其删除文件。如果上传的所有文件都在同一个文件夹中,那么名称就足够了(*)。

        毕竟,通过上传文件,您是在强迫您在 PC 中保存您要删除的文件的副本(如果您删除了本地文件怎么办?难道您不能删除服务器中的文件吗? )

        (*) 一定要进行安全检查,这样没有人可以将..\..\WEB-INF\web.xml 作为参数传递。

        【讨论】:

        • 感谢您的回复!我同意...只输入我选择的文件名,创建文件名,然后删除它会更简单。如何从 HttpServletRequest 中获取这个(只是文件名)?我查看了 getLocalName()、getContextPath()、getPathInfo()、getPathTranslated()...似乎没有一个返回我正在寻找的东西。原谅我对这件事的无知,我对此很陌生。
        • 不,不,不。忘记文件。它就像一个 HTML select 一样简单,列出所有可删除的路径。只需使用“常规”HTTP 请求参数即可。
        • 这将列出所有文件,不是吗?我希望能够通过 fileChooser 在 JSP 上单独选择一个文件,将其传递给 Servlet,然后让 Servlet 删除该文件。