1

So at one point of my code, I create an audioinputstream:

try{
     File f = new File(main.getWavFileName(0, tab));
     AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(f);
     audioInputStream.close();
     audioInputStream = null;
     f = null;
}catch(Exception e) {e.printStackTrace();}

However, when I try to delete the referenced file, I get a FileSystemException error saying that the file is in use by another process. When I comment out the above code, I no longer get the error and am able to delete the file. Is there a way to force the AudioInputStream to stop referencing the file?

Edit: The code calling the delete - however, I have tested to see that the above code is finished executing prior to calling the delete (just using a system.out.print before and after to ensure that the code is not currently running - don't know a better way)

File f[] = new File(rootPath + File.separator + directoryNames.get(t)).listFiles();
for(File f2 : f)
{
    try {
        Files.delete(Paths.get(f2.getAbsolutePath()));
    } catch (IOException e) {
    e.printStackTrace();    
    }
}

Edit: Just FYI, I reduced the code I had inside the try statement to the bare minimum that you see above, and I still get the error, I am not trying to create the stream for no reason.

Edit: I am running windows 7, but I don't have any error deleting the file when I comment out the code. The exception I get is:

java.nio.file.FileSystemException: C:\Users\Fred\Desktop\test patient\June 24th, 2011\s1.wav: The process cannot access the file because it is being used by another process.

at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:86)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
at sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:268)
at sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:103)
at java.nio.file.Files.delete(Files.java:1071)
at main.closeTab(main.java:349)
at MainButtonActionListener.actionPerformed(main.java:436)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:289)
at java.awt.Component.processMouseEvent(Component.java:6504)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6269)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4860)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4686)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2713)
at java.awt.Component.dispatchEvent(Component.java:4686)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707)
at java.awt.EventQueue.access$000(EventQueue.java:101)
at java.awt.EventQueue$3.run(EventQueue.java:666)
at java.awt.EventQueue$3.run(EventQueue.java:664)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:680)
at java.awt.EventQueue$4.run(EventQueue.java:678)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:677)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Fred Howard
  • 11
  • 1
  • 3
  • Are you running Windows 7? And where is this file located? You may be experiencing some UAC related issues. Also, can you post the exception that you get in your question? – Dharini Chandrasekaran Jul 03 '12 at 17:50
  • 1
    I ran this code and I can delete the file after the close method is called, but see @GETah's answer for clean stream handling. Also can you post the code where you are actually calling delete? Maybe you have a race going on that we can't see. – Jeff Storey Jul 03 '12 at 17:52
  • Go through this post http://windowsxp.mvps.org/processlock.htm to find which process is locking the file. The exact stack trace and exception will be helpful. Also you might want to close your stream in a finally block instead of the try block. – Egalitarian Jul 03 '12 at 17:57
  • The file is located on my desktop, and I have checked through the process explorer and the only references I found were from javaw.exe. – Fred Howard Jul 03 '12 at 18:06
  • 1
    see this link: [Trouble with AudioInputStream](http://www.javaprogrammingforums.com/file-i-o-other-i-o-streams/16477-trouble-audioinputstream-not-releasing-file-hook.html). It helped me in the past. Regards, –  Oct 08 '12 at 01:20

4 Answers4

6

when I try to delete the referenced file, I get a FileSystemException error saying that the file is in use by another process

That other process is probably you :) Your code won't close the stream in case there is an exception in the try clause. In a nutshell, this audioInputStream.close(); never gets called in case there is an exception thrown before the call. You should always do the following when dealing with streams:

Stream stream = null;
try{
  // Instantiate and do something with stream
}catch(...){

}finally{
  // Close your streams here
}

This ensures your streams are closed whatever the try catch block does.

GETah
  • 20,922
  • 7
  • 61
  • 103
  • +1 for good practice, but this may not be the solution to the problem – Jeff Storey Jul 03 '12 at 17:56
  • Thank you. I am sure this will help out narrow the problem to a specific area :) – GETah Jul 03 '12 at 17:58
  • Thank you for the good coding practice, I will make sure to use this in the future. However, I haven't gotten any exception generated from the code I was using, and switching to this format doesn't solve the problem. Do you have any ideas beyond this? – Fred Howard Jul 03 '12 at 18:02
0

It also looks like you are doing the delete on the event dispatch thread. What thread is the opening/closing of the audio stream happening on? Can you be sure they are happening in order (I know you added some printlns, but I'm curious as to any possible threading issues here).

I have written an isolated code block here that opens/closes the file and then deletes it. Give this a try and see if it works for you (works here no problem)

import java.io.File;
import java.io.IOException;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;

public class AudioTest
{

    public static void main(String[] args) throws Exception
    {
        File file = new File(args[0]);
        AudioTest test = new AudioTest();
        test.openCloseFile(file);
        file.delete();
    }

    private void openCloseFile(File file) throws IOException, UnsupportedAudioFileException
    {
        AudioInputStream audioInputStream = null;
        try
        {
            audioInputStream = AudioSystem.getAudioInputStream(file);
        }
        finally
        {
            if (audioInputStream != null)
            {
                audioInputStream.close();
            }
        }
    }
}
Jeff Storey
  • 56,312
  • 72
  • 233
  • 406
  • Hi Jeff, I tried running this code, and unfortunately I still get the error. In my implementation, instead of getting the file from main args, I just entered it straight into the program. Can you try doing this with Files.delete(Paths.get(file.getPath()));? This throws an exception when deleting a file that can't be deleted, file.delete() doesn't throw exceptions. Did you successfully delete the file with your code? – Fred Howard Jul 03 '12 at 18:16
  • What is Paths.getFile (I assume Files is a Guava call)? And yes, the file was successfully deleted. Have you tried stepping through the delete call with the debugger? – Jeff Storey Jul 03 '12 at 18:27
  • Its part of the JDK7 new input output. I haven't tried stepping through with a debugger yet, I'll try that next - just never had much experience with a debugger. Edit: Sorry, JRE7, jdk1.7 I think? Not sure how version naming goes. – Fred Howard Jul 03 '12 at 18:29
  • It does fail as well with using Files.delete(Paths.get(file.getPath()) – Jeff Storey Jul 03 '12 at 18:35
  • 2
    This may be related http://stackoverflow.com/questions/991489/i-cant-delete-a-file-in-java – Jeff Storey Jul 03 '12 at 18:40
  • 1
    Yea, you're right!!! Using System.gc() allows me to delete the file. Thanks for the help, sorry I don't have enough rep to give you +1 or anything =( – Fred Howard Jul 03 '12 at 18:47
  • That shouldn't be the way to do it though. This seems a bit buggy, but I'm not quite sure why. I would do some research to see if you can find out why this is happening though. – Jeff Storey Jul 03 '12 at 18:49
0

I just want to re-post this from a comment so it is easier to see, especially because it worked perfectly for me when editing and deleting a lot of files:

Try putting System.gc in your try block!

0

I faced the same issue, and this is how I solved it:

try{

 File f = new File("audioFile.wav");

 byte[] bytes = Files.readAllBytes(f.toPath());

 ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
                
 AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(byteArrayInputStream);
 // ...
 }
 catch (Exception ex) { ex.printStackTrace(); }
 //...

As far as I understand, the problem was with the AudioInputStream object.

When it gets the input stream from the provided audio file, it doesn't release it back to the OS even if you close the stream. I really don't know why, but I do know that the method Files.readAllBytes(Path path) ensures that the audio file is closed and released back to the OS as soon as all bytes have been read.