【问题标题】:Not able to Close and delete already opened .xls file thro' java code无法通过 Java 代码关闭和删除已打开的 .xls 文件
【发布时间】:2017-02-01 05:22:27
【问题描述】:

我正在尝试通过 java 代码删除目录, 现在 用例是: 如果文件已经打开,那么它应该先关闭它,然后我可以直接删除目录。

我试图使用 FileoutputStream 关​​闭文件,但我无法创建 FileoutputStream 的对象,它显示的错误如下 “该进程无法访问该文件,因为它正被另一个进程使用”

还有其他方法可以帮助我吗?

【问题讨论】:

  • 添加你的代码sn-p,
  • 否 - 如果另一个进程打开了文件(在 Windows 上,这是您的平台,因为 Linux 不关心另一个进程打开了文件),那么您对此无能为力来自爪哇。您需要使用特定于 Windows 的工具来确定打开哪个进程,并根据需要自动关闭该进程。
  • 这种方法行不通。您正在尝试打开一个新的文件句柄,并且只能关闭它。现有文件句柄仍保持打开状态。
  • 文件是否由您自己的 Java 应用程序打开并试图关闭文件?
  • @DevilsHnd 否。文件是手动打开的,需要通过我的 java 代码关闭以删除父文件夹

标签: java file


【解决方案1】:

如果您的 Java 应用程序可能使用 Runtime.getRuntime().exec() 方法或任何其他方式打开了您要删除的文件,则该文件必须是关闭后才能执行任务。当然,由于文件已打开,您也不能删除该文件的主文件夹(目录),因此需要先关闭该文件。这是一个完全有意义的操作系统保护措施,为什么我们要删除其他正在使用的东西?

为了关闭文件,您需要知道正在使用它的进程的名称,例如,如果一个名为 MyText.txt 的文本文件已用 MS Windows 打开NotePad.exe 那么您必须关闭保持 MyText.txt 文件处于打开状态的 NotePad.exe 进程。

下面我提供了一个简单的方法,如果您提供正确的进程名称,它可以为您关闭一个打开的外部进程。在我们上面的示例中,这将是 "Notepad.exe"

public static void killProcess(String processName) {
    // PLEASE NOTE: This method will currently Kill "ALL" 
    //              open processes of the supplied process 
    //              name unless commented code changes are 
    //              made.
    try {
        Runtime rt = Runtime.getRuntime();
        // For Windows OS...
        if (System.getProperty("os.name").toLowerCase().contains("windows")) {
            rt.exec("taskkill /T /F /IM " + processName);
            //rt.exec("taskkill /T /F /PID " + Long.parseLong(processName)); // Supply the PID value as string
            //rt.exec("taskkill /F /FI \"WINDOWTITLE eq " + processName + "\" /T"); // Supply the window title bar text.
            // If you want to kill only a single instance of the 
            // named process then get its PID value and use:
            // "taskkill /T /F /PID PID_Value"  OR you can provide
            // the window title and use:
            // "taskkill /F /FI \"WINDOWTITLE eq " + processName + "\" /T"
        }
        // For OSX And Linux OS's...
        else {
            rt.exec("sudo killall -9 '" + processName + "'");
            //rt.exec("kill -9 " + Long.parseLong(processName)); // Supply the PID value as string
            // If you want to kill only a single instance of the 
            // named process then get its PID value and use:
            // "kill -9 PID_Value"
        }
        rt.freeMemory();
    } 
    catch (IOException | SecurityException | IllegalArgumentException ex) {
        ex.printStackTrace();
    }
}

由于该方法代码开头的 cmets 状态,所有当前正在运行的进程名称所提供的进程将被终止。如果您只想终止进程的特定实例,例如我们上面的示例,并且您有四个其他 Notepad.exe 实例打开编辑其他文本文件,那么您需要将方法代码更改为:

rt.exec("taskkill /F /FI \"WINDOWTITLE eq " + processName + "\" /T");

而不是这个:

rt.exec("taskkill /T /F /IM " + processName);

当然你会这样称呼这个方法:

killProcess("MyText.txt - Notepad");

您在哪里提供应用程序窗口标题栏中的内容。上述方法完成后,您可以删除 MyText.txt 文件及其所在的文件夹,因为它不再被使用。

【讨论】:

  • 实际上用例是我正在创建一个文件夹结构,我正在尝试在其中创建一个 excel 文件。当用户第二次尝试再次运行代码时,必须删除以前的文件夹。但是如果用户已经打开了一些excel,那么我们无法删除现有目录,我无法通过它自己的代码关闭文件。我们应该先警告用户关闭文件。并让用户先做结账工作。它是唯一的解决方案还是还有其他的?
  • 我明白了...在您的特定情况下,您肯定希望用户首先关闭他们各自的文件(礼貌)。在这种情况下,我唯一能想到的就是创建一个带有计时器的附加线程,以不断尝试删除文件夹并故意捕获和忽略异常。当成功发生时,您可以在计时器停止并终止线程后在屏幕上显示一个消息框。
  • 是的。非常感谢你:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多