【问题标题】:Why are only SOME of the files and folders not deleted?为什么只有部分文件和文件夹没有被删除?
【发布时间】:2014-08-12 00:29:30
【问题描述】:

我正在从我的 servlet (output.txt) 和 XSL 文件(文件夹 generatedApps 及其内容)生成一些文件,然后将 XSL 转换生成的文件和文件夹打包到 ZIP 存档中。客户端下载 ZIP 存档后,我想删除它,以及其他文件和文件夹。

这是我的代码:

InputStream inputStream = new ByteArrayInputStream(request.getParameter("content")
        .getBytes("UTF-8"));
    try {
        TransformerFactory tFactory = new net.sf.saxon.TransformerFactoryImpl();
        Transformer transformer = tFactory.newTransformer(new StreamSource(
            getServletContext().getResourceAsStream("lib/GenerateGeddyJsCode.xsl")));
        FileOutputStream fos = new FileOutputStream("output.txt");
        transformer.transform(new StreamSource(inputStream), new StreamResult(fos));

        String appName = new Scanner(new File("output.txt")).useDelimiter("\\Z").next();

        ZipUsingJavaUtil zipper = new ZipUsingJavaUtil();
        zipper.zipFiles("generatedApps/" + appName, "generatedApps/" + appName + "Archive.zip");

        String path = "generatedApps/";
        String fileName = appName + "Archive.zip";
  File f = new File(path + fileName);       

  response.setContentType("application/zip");     
  response.setContentLength((int)f.length());  
  response.addHeader("Content-Disposition","attachment;filename=\"" + fileName + "\"");    
  byte[] arBytes = new byte[32768];     
  FileInputStream is = new FileInputStream(f);
  ServletOutputStream op = response.getOutputStream();     
  int count;
  while ((count = is.read(arBytes)) > 0)
  {
      op.write(arBytes, 0, count);     
  }
  op.flush();
  op.close();
  is.close();
  fos.close();
  inputStream.close();

  File toBeDel = new File("generatedApps/");
  GenerateGeddyJsCode.removeDirectory(toBeDel);

  File output = new File("output.txt");
  output.delete();

方法removeDirectory如下:

public static void removeDirectory(File dir) {
    if (dir.isDirectory()) {
        File[] files = dir.listFiles();
        if (files != null && files.length > 0) {
            for (File aFile : files) {
                removeDirectory(aFile);
            }
        }   
    } else {
        dir.delete();
    }
}

问题是最终只删除了 ZIP 存档(顺便说一句,存档在 generatedApps 内)。我试图关闭所有流,因为我读过未关闭的流会阻止删除。

我怎样才能删除剩余的文件和文件夹?

===================================== 编辑======= ==================================

我更新的删除方法:

public static void removeDirectory(File dir) {
if (dir.isDirectory()) {
    File[] files = dir.listFiles();
    if (files != null && files.length > 0) {
        for (File aFile : files) {
            removeDirectory(aFile);
        }
    } else if (files.length == 0) {
        dir.delete();
    }

} 
dir.delete();

}

还是不行。

===================================== 编辑2====== =================================== 补充:

InputStream inStream = getServletContext().getResourceAsStream("lib/GenerateGeddyJsCode.xsl");
StreamSource inStreamSource = new StreamSource(inStream);
Transformer transformer = tFactory.newTransformer(inStreamSource);

及以后的inStream.close()。还是不行。

【问题讨论】:

  • 在你的代码中你永远不会删除目录...
  • 问题是它甚至没有从文件夹中删除我的文件
  • 首先添加 delete() 以防文件夹为空,更正问题中的代码,然后我们继续... :) 另外,检查 delete() 是否返回 'true'
  • 您不需要在 response.getOutputStream 上使用文件 ZipOutputStream 作为 XSLT 结果。
  • 更新了...还是什么都没有

标签: java tomcat servlets stream tomcat6


【解决方案1】:

您可以检查 Zip 实用程序是否正确关闭文件... 您是否有权访问 ZipUsingJavaUtil 类源?

  • 必须关闭 zip 文件中的每个条目。
  • 为 zip 写入过程打开的每个文件输入流都应该是 关闭。

检查以下示例: http://www.journaldev.com/957/java-zip-example-to-zip-single-file-and-a-directory-recursively

【讨论】:

  • 我太专注于我上面介绍的代码,以至于我没有看拉链类...谢谢!
【解决方案2】:

如果您使用的是 linux,则可以执行一些命令行版本的删除文件。

Runtime.getRuntime().exec("rm -rf");

'r' 标志表示递归,意味着从基开始,此命令删除目录和所有子目录。

'f' 标志强制它,不问你“你想删除 xxxx.txt 吗?”每个文件。

你也可以做类似的事情

Runtime.getRuntime().exec("rm -rf *.java");

如果您只是删除 Java 文件。此外,windows 和 mac 有一个 shell 删除文件/删除目录命令。希望这会有所帮助

【讨论】:

    【解决方案3】:

    1) 重新格式化您的代码...什么都看不到

    2) 在 finally 块中关闭您的流

    尝试 { ... } 捕捉(异常 e){ ...处理你的异常 } 最后 { 关闭你必须关闭的东西! }

    3) “我试图关闭所有流,因为我读过未关闭的流会阻止删除。” 好吧,我猜你还有打开的文件句柄。即使是外部文件句柄也可以防止删除。是否有任何防病毒程序扫描文件?在 Internet 上搜索用于检测打开文件句柄的工具。

    4) 您还可以测试 aFile.deleteOnExit() 是否有效。 "deleteOnExit" 尝试在 JVM 关闭时删除文件。

    祝你好运

    【讨论】:

      【解决方案4】:

      我想在评论中发布此内容,但我没有足够的声誉。我试过你的方法来删除文件,没关系,但如果你可以删除“output.txt”文件应该是因为有一个对象使用该文件,你似乎关闭了所有流,但检查了我看到你使用的代码获取 appName 的 Scanner 对象可能是问题所在,因为 Scanner 对象指向您的“output.txt”文件。

      改变这个:

      String appName = new Scanner(new File("output.txt")).useDelimiter("\\Z").next();
      

      对于这样的事情:

      Scanner scanObject = new Scanner(new File("output.txt"));
      String appName = scanObject.useDelimiter("\\Z").next();
      scanObject.close();
      

      我不确定 new Scanner(new File("output.txt"));我认为 scanObject.close() 也应该关闭您传递给 Scanner 对象的 File 对象,如果没有,请尝试将其分开并在使用扫描仪后关闭 File 对象。

      【讨论】:

      • 这有助于 output.txt 文件,但 XSLT 生成的文件仍然存在...
      • 我看到了你的最后更新,我认为它应该可以工作,我没有看到任何未关闭的流,所以也许 saxon 有一个错误,检查这个:stackoverflow.com/questions/17998881/…也许你可以尝试另一个版本
      【解决方案5】:

      您永远不会在您的 removeDirectory 方法中删除目录。

      您需要删除 else 以使其无条件执行(对于目录和非目录)。

      public static void removeDirectory(File dir) {
          if (dir.isDirectory()) {
              File[] files = dir.listFiles();
              if (files != null && files.length > 0) {
                  for (File aFile : files) {
                      removeDirectory(aFile);
                  }
              }   
          }// else {
              dir.delete();
      //    }
      }
      

      【讨论】:

      • 对removeDirectory(aFile)的递归调用;是正确的
      • 注意到了。修好了。
      • 删除斜线是个坏主意...现在它甚至不会删除 ZIP 存档...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-18
      • 2019-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多