即使 file.exists()、file.canRead()、file.canWrite()、file.canExecute() 都返回 true,file.delete() 返回 false

发布于 2024-07-23 10:23:40 字数 840 浏览 8 评论 0原文

我正在尝试使用 FileOutputStream 在其中写入内容后删除一个文件。 这是我用来编写的代码:

private void writeContent(File file, String fileContent) {
    FileOutputStream to;
    try {
        to = new FileOutputStream(file);
        to.write(fileContent.getBytes());
        to.flush();
        to.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

正如所见,我刷新并关闭流,但是当我尝试删除时,file.delete() 返回 false。

我在删除之前检查了文件是否存在,以及:file.exists()file.canRead()file.canWrite() >、file.canExecute() 全部返回 true。 调用这些方法后,我尝试 file.delete() 并返回 false。

我是不是做错了什么?

I'm trying to delete a file, after writing something in it, with FileOutputStream. This is the code I use for writing:

private void writeContent(File file, String fileContent) {
    FileOutputStream to;
    try {
        to = new FileOutputStream(file);
        to.write(fileContent.getBytes());
        to.flush();
        to.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

As it is seen, I flush and close the stream, but when I try to delete, file.delete() returns false.

I checked before deletion to see if the file exists, and: file.exists(), file.canRead(), file.canWrite(), file.canExecute() all return true. Just after calling these methods I try file.delete() and returns false.

Is there anything I've done wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(17

北凤男飞 2024-07-30 10:23:40

Java 中的另一个错误。 我很少找到他们,这只是我十年职业生涯中的第二次。 正如其他人提到的,这是我的解决方案。 我没有使用过System.gc()。 但就我而言,这绝对是至关重要的。 诡异的? 是的!

finally
{
    try
    {
        in.close();
        in = null;
        out.flush();
        out.close();
        out = null;
        System.gc();
    }
    catch (IOException e)
    {
        logger.error(e.getMessage());
        e.printStackTrace();
    }
}

Another bug in Java. I seldom find them, only my second in my 10 year career. This is my solution, as others have mentioned. I have nether used System.gc(). But here, in my case, it is absolutely crucial. Weird? YES!

finally
{
    try
    {
        in.close();
        in = null;
        out.flush();
        out.close();
        out = null;
        System.gc();
    }
    catch (IOException e)
    {
        logger.error(e.getMessage());
        e.printStackTrace();
    }
}
活雷疯 2024-07-30 10:23:40

这个伎俩竟然奏效了,真是太奇怪了。 问题是,当我之前读取文件内容时,我使用了 BufferedReader。 读完后,我关闭了缓冲区。

与此同时,我进行了切换,现在我正在使用 FileInputStream 读取内容。 读完后我也关闭了流。 现在它正在发挥作用。

问题是我对此没有解释。

我不知道 BufferedReader 和 FileOutputStream 不兼容。

It was pretty odd the trick that worked. The thing is when I have previously read the content of the file, I used BufferedReader. After reading, I closed the buffer.

Meanwhile I switched and now I'm reading the content using FileInputStream. Also after finishing reading I close the stream. And now it's working.

The problem is I don't have the explanation for this.

I don't know BufferedReader and FileOutputStream to be incompatible.

长伴 2024-07-30 10:23:40

我尝试了这个简单的事情,它似乎有效。

file.setWritable(true);
file.delete();

这个对我有用。

如果这不起作用,请尝试在 Linux 上使用 sudo 运行 Java 应用程序,在 Windows 上则以管理员身份运行。 只是为了确保 Java 有权更改文件属性。

I tried this simple thing and it seems to be working.

file.setWritable(true);
file.delete();

It works for me.

If this does not work try to run your Java application with sudo if on linux and as administrator when on windows. Just to make sure Java has rights to change the file properties.

疾风者 2024-07-30 10:23:40

在尝试删除/重命名任何文件之前,您必须确保所有读取器或写入器(例如:BufferedReader/InputStreamReader/BufferedWriter)正确关闭。

当您尝试从文件读取数据或向文件写入数据时,该文件将由进程保存,直到程序执行完成后才会释放。 如果要在程序结束之前执行删除/重命名操作,则必须使用 java.io.* 类附带的 close() 方法。

Before trying to delete/rename any file, you must ensure that all the readers or writers (for ex: BufferedReader/InputStreamReader/BufferedWriter) are properly closed.

When you try to read/write your data from/to a file, the file is held by the process and not released until the program execution completes. If you want to perform the delete/rename operations before the program ends, then you must use the close() method that comes with the java.io.* classes.

转身以后 2024-07-30 10:23:40

正如 Jon Skeet 评论的那样,您应该在 finally {...} 块中关闭文件,以确保它始终处于关闭状态。 并且,不要使用 e.printStackTrace 吞掉异常,而是简单地不捕获异常并将其添加到方法签名中。 如果您出于任何原因不能,至少这样做:

catch(IOException ex) {
    throw new RuntimeException("Error processing file XYZ", ex);
}

现在,问题#2:

如果您这样做会怎样:

...
to.close();
System.out.println("Please delete the file and press <enter> afterwards!");
System.in.read();
...

您能够删除该文件吗?

此外,文件在关闭时也会被刷新。 我使用 IOUtils.closeQuietly(...),因此在尝试关闭文件之前,我使用刷新方法来确保文件的内容存在(IOUtils.closeQuietly 不会抛出异常)。 像这样的事情:

...
try {
    ...
    to.flush();
} catch(IOException ex) {
    throw new CannotProcessFileException("whatever", ex);
} finally {
    IOUtils.closeQuietly(to);
}

所以我知道文件的内容就在那里。 因为通常对我来说重要的是文件的内容被写入,而不是文件是否可以关闭,因此文件是否关闭实际上并不重要。 就您而言,重要的是,我建议您自己关闭文件并根据情况处理任何异常。

As Jon Skeet commented, you should close your file in the finally {...} block, to ensure that it's always closed. And, instead of swallowing the exceptions with the e.printStackTrace, simply don't catch and add the exception to the method signature. If you can't for any reason, at least do this:

catch(IOException ex) {
    throw new RuntimeException("Error processing file XYZ", ex);
}

Now, question number #2:

What if you do this:

...
to.close();
System.out.println("Please delete the file and press <enter> afterwards!");
System.in.read();
...

Would you be able to delete the file?

Also, files are flushed when they're closed. I use IOUtils.closeQuietly(...), so I use the flush method to ensure that the contents of the file are there before I try to close it (IOUtils.closeQuietly doesn't throw exceptions). Something like this:

...
try {
    ...
    to.flush();
} catch(IOException ex) {
    throw new CannotProcessFileException("whatever", ex);
} finally {
    IOUtils.closeQuietly(to);
}

So I know that the contents of the file are in there. As it usually matters to me that the contents of the file are written and not if the file could be closed or not, it really doesn't matter if the file was closed or not. In your case, as it matters, I would recommend closing the file yourself and treating any exceptions according.

余生再见 2024-07-30 10:23:40

您没有理由不能删除该文件。 我想看看谁拥有这个文件。 在 unix/linux 中,您可以使用 lsof 实用程序来检查哪个进程锁定了文件。 在 Windows 中,您可以使用进程资源管理器。

对于 lsof,就像说一样简单:

lsof /path/and/name/of/the/file

对于进程资源管理器,您可以使用查找菜单并输入文件名来显示句柄,该句柄将指向锁定文件的进程。

这里有一些代码可以完成我认为您需要做的事情:

FileOutputStream to;

try {
    String file = "/tmp/will_delete.txt";
    to = new FileOutputStream(file );
    to.write(new String("blah blah").getBytes());
    to.flush();
    to.close();
    File f = new File(file);
    System.out.print(f.delete());
} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

它在 OS X 上运行良好。我还没有在 Windows 上测试它,但我怀疑它也应该在 Windows 上运行。 我也承认在 Windows wrt 文件处理中看到了一些意外的行为。

There is no reason you should not be able to delete this file. I would look to see who has a hold on this file. In unix/linux, you can use the lsof utility to check which process has a lock on the file. In windows, you can use process explorer.

for lsof, it's as simple as saying:

lsof /path/and/name/of/the/file

for process explorer you can use the find menu and enter the file name to show you the handle which will point you to the process locking the file.

here is some code that does what I think you need to do:

FileOutputStream to;

try {
    String file = "/tmp/will_delete.txt";
    to = new FileOutputStream(file );
    to.write(new String("blah blah").getBytes());
    to.flush();
    to.close();
    File f = new File(file);
    System.out.print(f.delete());
} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

It works fine on OS X. I haven't tested it on windows but I suspect it should work on Windows too. I will also admit seeing some unexpected behavior on Windows w.r.t. file handling.

长梦不多时 2024-07-30 10:23:40

如果您正在使用 Eclipse IDE,这可能意味着您在上次启动应用程序时没有关闭该文件。 当我尝试删除文件时出现相同的错误消息时,这就是原因。 看来,Eclipse IDE 在应用程序终止后不会关闭所有文件。

If you are working in Eclipse IDE, that could mean that you haven't close the file in the previous launch of the application. When I had the same error message at trying to delete a file, that was the reason. It seems, Eclipse IDE doesn't close all files after termination of an application.

傲娇萝莉攻 2024-07-30 10:23:40

希望这会有所帮助。 我遇到了类似的问题,在我的 java 代码将内容复制到其他文件夹后,我无法删除我的文件。 经过广泛的谷歌搜索,我显式声明了每个文件操作相关的变量,并调用每个文件操作对象的 close() 方法,并将它们设置为 NULL。 然后,有一个名为 System.gc() 的函数,它将清除文件 i/o 映射(我不确定,我只是告诉网站上给出的内容)。

这是我的示例代码:

public void start() {
    File f = new File(this.archivePath + "\\" + this.currentFile.getName());
    this.Copy(this.currentFile, f);

    if(!this.currentFile.canWrite()){
        System.out.println("Write protected file " +
           this.currentFile.getAbsolutePath());

        return;
    }


    boolean ok = this.currentFile.delete();
    if(ok == false){
        System.out.println("Failed to remove " + this.currentFile.getAbsolutePath());
        return;
    }
}

private void Copy(File source, File dest) throws IOException {
    FileInputStream fin;
    FileOutputStream fout;
    FileChannel cin = null, cout = null;
    try {
        fin = new FileInputStream(source);
        cin = fin.getChannel();
        fout = new FileOutputStream(dest);
        cout = fout.getChannel();

        long size = cin.size();
        MappedByteBuffer buf = cin.map(FileChannel.MapMode.READ_ONLY, 0, size);

        cout.write(buf);
        buf.clear();
        buf = null;

        cin.close();
        cin = null;

        fin.close();
        fin = null;

        cout.close();
        cout = null;

        fout.close();
        fout = null;

        System.gc();

    } catch (Exception e){
        this.message = e.getMessage();
        e.printStackTrace();
    }
}

Hopefully this will help. I came across similar problem where i couldn't delete my file after my java code made a copy of the content to the other folder. After extensive googling, i explicitly declared every single file operation related variables and called the close() method of each file operation object, and set them to NULL. Then, there is a function called System.gc(), which will clear up the file i/o mapping (i'm not sure, i just tell what is given on the web sites).

Here is my example code:

public void start() {
    File f = new File(this.archivePath + "\\" + this.currentFile.getName());
    this.Copy(this.currentFile, f);

    if(!this.currentFile.canWrite()){
        System.out.println("Write protected file " +
           this.currentFile.getAbsolutePath());

        return;
    }


    boolean ok = this.currentFile.delete();
    if(ok == false){
        System.out.println("Failed to remove " + this.currentFile.getAbsolutePath());
        return;
    }
}

private void Copy(File source, File dest) throws IOException {
    FileInputStream fin;
    FileOutputStream fout;
    FileChannel cin = null, cout = null;
    try {
        fin = new FileInputStream(source);
        cin = fin.getChannel();
        fout = new FileOutputStream(dest);
        cout = fout.getChannel();

        long size = cin.size();
        MappedByteBuffer buf = cin.map(FileChannel.MapMode.READ_ONLY, 0, size);

        cout.write(buf);
        buf.clear();
        buf = null;

        cin.close();
        cin = null;

        fin.close();
        fin = null;

        cout.close();
        cout = null;

        fout.close();
        fout = null;

        System.gc();

    } catch (Exception e){
        this.message = e.getMessage();
        e.printStackTrace();
    }
}
一笔一画续写前缘 2024-07-30 10:23:40

答案是当您加载文件时,您需要在任何代码行中应用“关闭”方法,这对我有用

the answer is when you load the file, you need apply the "close" method, in any line of code, works to me

债姬 2024-07-30 10:23:40

ruby 中曾经存在一个问题,Windows 中的文件需要“fsync”才能在写入并关闭文件后真正能够翻转并重新读取文件。 也许这是一个类似的表现(如果是这样,我认为确实是 Windows 错误)。

There was a problem once in ruby where files in windows needed an "fsync" to actually be able to turn around and re-read the file after writing it and closing it. Maybe this is a similar manifestation (and if so, I think a windows bug, really).

无人问我粥可暖 2024-07-30 10:23:40

此处列出的解决方案均不适用于我的情况。 我的解决方案是使用 while 循环,尝试删除文件,为了安全起见,限制为 5 秒(可配置)。

File f = new File("/path/to/file");

int limit = 20; //Only try for 5 seconds, for safety
while(!f.delete() && limit > 0){
    synchronized(this){
        try {
            this.wait(250); //Wait for 250 milliseconds
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    limit--;
}

使用上面的循环无需进行任何手动垃圾收集或将流设置为空等。

None of the solutions listed here worked in my situation. My solution was to use a while loop, attempting to delete the file, with a 5 second (configurable) limit for safety.

File f = new File("/path/to/file");

int limit = 20; //Only try for 5 seconds, for safety
while(!f.delete() && limit > 0){
    synchronized(this){
        try {
            this.wait(250); //Wait for 250 milliseconds
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    limit--;
}

Using the above loop worked without having to do any manual garbage collecting or setting the stream to null, etc.

始终不够 2024-07-30 10:23:40

问题可能是文件仍然被视为由程序打开和锁定; 或者它可能是您的程序中打开它的一个组件,因此您必须确保使用 dispose() 方法来解决该问题。
JFrame框架;
....
框架.dispose();

The problem could be that the file is still seen as opened and locked by a program; or maybe it is a component from your program that it had been opened in, so you have to ensure you use the dispose() method to solve that problem.
i.e. JFrame frame;
....
frame.dispose();

天煞孤星 2024-07-30 10:23:40

您必须关闭所有流或使用 try-with-resource 块

static public String head(File file) throws FileNotFoundException, UnsupportedEncodingException, IOException
{
    final String readLine;
    try (FileInputStream fis = new FileInputStream(file);
            InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
            LineNumberReader lnr = new LineNumberReader(isr))
    {
        readLine = lnr.readLine();
    }
    return readLine;
}

You have to close all of the streams or use try-with-resource block

static public String head(File file) throws FileNotFoundException, UnsupportedEncodingException, IOException
{
    final String readLine;
    try (FileInputStream fis = new FileInputStream(file);
            InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
            LineNumberReader lnr = new LineNumberReader(isr))
    {
        readLine = lnr.readLine();
    }
    return readLine;
}
鹿港小镇 2024-07-30 10:23:40

如果 file.delete() 发送 false 那么在大多数情况下你的 Bufferedreader 句柄将不会被关闭。 就在附近,它似乎对我来说正常工作。

if file.delete() is sending false then in most of the cases your Bufferedreader handle will not be closed. Just close and it seems to work for me normally.

末が日狂欢 2024-07-30 10:23:40

我在 Windows 上也遇到了同样的问题。 我曾经在 scala 中逐行读取文件,

Source.fromFile(path).getLines()

现在我将其作为一个整体读取,

import org.apache.commons.io.FileUtils._

// encoding is null for platform default
val content=readFileToString(new File(path),null.asInstanceOf[String])

在读取后正确关闭文件,现在

new File(path).delete

可以正常工作。

I had the same problem on Windows. I used to read the file in scala line by line with

Source.fromFile(path).getLines()

Now I read it as a whole with

import org.apache.commons.io.FileUtils._

// encoding is null for platform default
val content=readFileToString(new File(path),null.asInstanceOf[String])

which closes the file properly after reading and now

new File(path).delete

works.

若沐 2024-07-30 10:23:40

对于 Eclipse/NetBeans

重新启动您的 IDE 并再次运行您的代码,这对我来说只是一个小时的挣扎后的技巧工作。

这是我的代码:

File file = new File("file-path");
if(file.exists()){
  if(file.delete()){
     System.out.println("Delete");
  }
  else{

       System.out.println("not delete");
  }
}

输出:

删除

FOR Eclipse/NetBeans

Restart your IDE and run your code again this is only trick work for me after one hour long struggle.

Here is my code:

File file = new File("file-path");
if(file.exists()){
  if(file.delete()){
     System.out.println("Delete");
  }
  else{

       System.out.println("not delete");
  }
}

Output:

Delete

病毒体 2024-07-30 10:23:40

可能发生这种情况的另一个极端情况是:如果您通过 URL 读取/写入 JAR 文件,然后尝试在同一 JVM 会话中删除同一文件。

File f = new File("/tmp/foo.jar");
URL j = f.toURI().toURL();

URL u = new URL("jar:" + j + "!/META-INF/MANIFEST.MF");
URLConnection c = u.openConnection();

// open a Jar entry in auto-closing manner
try (InputStream i = c.getInputStream()) {

    // just read some stuff; for demonstration purposes only
    byte[] first16 = new byte[16];
    i.read(first16);
    System.out.println(new String(first16));
}

// ...

// i is now closed, so we should be good to delete the jar; but...
System.out.println(f.delete());     // says false!

原因是 Java 的内部 JAR 文件处理逻辑倾向于缓存 JarFile 条目:

// inner class of `JarURLConnection` that wraps the actual stream returned by `getInputStream()`

class JarURLInputStream extends FilterInputStream {
    JarURLInputStream(InputStream var2) {
        super(var2);
    }

    public void close() throws IOException {
        try {
            super.close();
        } finally {

            // if `getUseCaches()` is set, `jarFile` won't get closed!

            if (!JarURLConnection.this.getUseCaches()) {
                JarURLConnection.this.jarFile.close();
            }
        }
    }
}

以及每个 JarFile (更确切地说,底层的 ZipFile 结构)将持有文件的句柄,从构建时直到调用 close()

public ZipFile(File file, int mode, Charset charset) throws IOException {
    // ...

    jzfile = open(name, mode, file.lastModified(), usemmap);

    // ...
}

// ...

private static native long open(String name, int mode, long lastModified,
                                boolean usemmap) throws IOException;

此 NetBeans 问题


显然有两种方法可以“修复”此问题:

  • 您可以禁用 JAR 文件缓存 - 对于当前的 URLConnection 或所有未来的 URLConnection(全局)在当前 JVM 会话中:

    URL u = new URL("jar:" + j + "!/META-INF/MANIFEST.MF"); 
      URLConnection c = u.openConnection(); 
    
      // 仅适用于 c 
      c.setUseCaches(false); 
    
      // 全局;   由于某种原因这个方法不是静态的, 
      // 所以我们仍然需要通过 URLConnection 实例访问它:( 
      c.setDefaultUseCaches(false); 
      
  • [黑客警告!] 使用完 JarFile 后,您可以手动将其从缓存中清除。 缓存管理器 sun.net.www.protocol.jar.JarFileFactory 是包私有的,但是一些反射魔法可以为您完成工作:

    类 JarBridge { 
    
          static void closeJar(URL url) 抛出异常 { 
    
              // JarFileFactory jarFactory = JarFileFactory.getInstance(); 
              类   jarFactoryClazz = Class.forName("sun.net.www.protocol.jar.JarFileFactory"); 
              方法 getInstance = jarFactoryClazz.getMethod("getInstance"); 
              getInstance.setAccessible(true); 
              对象 jarFactory = getInstance.invoke(jarFactoryClazz); 
    
              // JarFile jarFile = jarFactory.get(url); 
              方法 get = jarFactoryClazz.getMethod("get", URL.class); 
              get.setAccessible(true); 
              对象 jarFile = get.invoke(jarFactory, url); 
    
              // jarFactory.close(jarFile); 
              方法 close = jarFactoryClazz.getMethod("close", JarFile.class); 
              关闭.setAccessible(true); 
              //noinspection JavaReflectionInvocation 
              close.invoke(jarFactory, jarFile); 
    
              // jarFile.close(); 
              ((JarFile) jarFile).close(); 
          } 
      } 
    
      // 在你的代码中: 
    
      // i 现在已关闭,所以我们应该删除该 jar 
      JarBridge.closeJar(j); 
      System.out.println(f.delete());   // 说的是真的,唷。 
      

请注意: 所有这些基于 Java 8 代码库 (1.8.0_144); 它们可能无法与其他/更高版本一起使用。

Another corner case that this could happen: if you read/write a JAR file through a URL and later try to delete the same file within the same JVM session.

File f = new File("/tmp/foo.jar");
URL j = f.toURI().toURL();

URL u = new URL("jar:" + j + "!/META-INF/MANIFEST.MF");
URLConnection c = u.openConnection();

// open a Jar entry in auto-closing manner
try (InputStream i = c.getInputStream()) {

    // just read some stuff; for demonstration purposes only
    byte[] first16 = new byte[16];
    i.read(first16);
    System.out.println(new String(first16));
}

// ...

// i is now closed, so we should be good to delete the jar; but...
System.out.println(f.delete());     // says false!

Reason is that the internal JAR file handling logic of Java, tends to cache JarFile entries:

// inner class of `JarURLConnection` that wraps the actual stream returned by `getInputStream()`

class JarURLInputStream extends FilterInputStream {
    JarURLInputStream(InputStream var2) {
        super(var2);
    }

    public void close() throws IOException {
        try {
            super.close();
        } finally {

            // if `getUseCaches()` is set, `jarFile` won't get closed!

            if (!JarURLConnection.this.getUseCaches()) {
                JarURLConnection.this.jarFile.close();
            }
        }
    }
}

And each JarFile (rather, the underlying ZipFile structure) would hold a handle to the file, right from the time of construction up until close() is invoked:

public ZipFile(File file, int mode, Charset charset) throws IOException {
    // ...

    jzfile = open(name, mode, file.lastModified(), usemmap);

    // ...
}

// ...

private static native long open(String name, int mode, long lastModified,
                                boolean usemmap) throws IOException;

There's a good explanation on this NetBeans issue.


Apparently there are two ways to "fix" this:

  • You can disable the JAR file caching - for the current URLConnection, or for all future URLConnections (globally) in the current JVM session:

    URL u = new URL("jar:" + j + "!/META-INF/MANIFEST.MF");
    URLConnection c = u.openConnection();
    
    // for only c
    c.setUseCaches(false);
    
    // globally; for some reason this method is not static,
    // so we still need to access it through a URLConnection instance :(
    c.setDefaultUseCaches(false);
    
  • [HACK WARNING!] You can manually purge the JarFile from the cache when you are done with it. The cache manager sun.net.www.protocol.jar.JarFileFactory is package-private, but some reflection magic can get the job done for you:

    class JarBridge {
    
        static void closeJar(URL url) throws Exception {
    
            // JarFileFactory jarFactory = JarFileFactory.getInstance();
            Class<?> jarFactoryClazz = Class.forName("sun.net.www.protocol.jar.JarFileFactory");
            Method getInstance = jarFactoryClazz.getMethod("getInstance");
            getInstance.setAccessible(true);
            Object jarFactory = getInstance.invoke(jarFactoryClazz);
    
            // JarFile jarFile = jarFactory.get(url);
            Method get = jarFactoryClazz.getMethod("get", URL.class);
            get.setAccessible(true);
            Object jarFile = get.invoke(jarFactory, url);
    
            // jarFactory.close(jarFile);
            Method close = jarFactoryClazz.getMethod("close", JarFile.class);
            close.setAccessible(true);
            //noinspection JavaReflectionInvocation
            close.invoke(jarFactory, jarFile);
    
            // jarFile.close();
            ((JarFile) jarFile).close();
        }
    }
    
    // and in your code:
    
    // i is now closed, so we should be good to delete the jar
    JarBridge.closeJar(j);
    System.out.println(f.delete());     // says true, phew.
    

Please note: All this is based on Java 8 codebase (1.8.0_144); they may not work with other / later versions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文