由于 javaFx MediaPlayer,无法删除 .mp3 文件

Unable to delete .mp3 file due to javaFx MediaPlayer

我正在研究我的高中顶点。这是一个程序,用户可以在其中从 Internet 下载歌曲并以有组织的方式存储它们并播放它们。我的程序必须包含一项功能,用户只需按一下按钮即可删除指定的 .mp3 文件。我在 MediaPlayer 上尝试了 .dispose() 方法,然后尝试删除似乎不起作用的文件。它会产生一个错误,指出 .mp3 文件仍在使用中。我将如何阻止 Javafx 访问该文件?我在网上搜索了答案,但 none 的答案符合我的需要。如果有人可以为我提供一些代码来解决我的问题,将不胜感激! 下面是一个可重现的迷你示例!

JavaFxMp3WavPlayer

package mediaplayerjavafx;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Paths;
import javafx.application.Application;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;

public class JavaFxMp3WavPlayer extends Application {

    public static void main(String[] args) throws MalformedURLException, IOException {
        launch(args);

    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setTitle("My");
        Button button = new Button("Delete Song File!");
        Scene scene = new Scene(button, 200, 100);
        stage.setScene(scene);
        stage.show();
        File file = new File("C:\Users\John Doe\OneDrive\Desktop\YourLieInAprilTest\Mp3Test.mp3");
        String path = file.toURI().toASCIIString();
        Media media = new Media(path);
        MediaPlayer mediaPlayer = new MediaPlayer(media);
        button.setOnAction(new EventHandler() {
            @Override
            public void handle(Event arg0) {
                deleteMusicFile(mediaPlayer);
            }
        });
        mediaPlayer.play();
    }

    public void deleteMusicFile(MediaPlayer mediaPlayer) {
        mediaPlayer.stop();
        mediaPlayer.dispose();
        try {
            Files.delete(Paths.get("C:\Users\John Doe\OneDrive\Desktop\YourLieInAprilTest\Mp3Test.mp3"));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

上面的class本质上是创建一个MediaPlayer对象并运行指定的.mp3文件。然后,当您按下按钮时,它将使用 .stop() 方法停止 MediaPlayer,然后使用 .dispose() 方法处理 MediaPlayer。然后它会尝试删除导致错误的文件。

模块信息

module MotisHarmony {
    requires javafx.swt;
    requires javafx.base;
    requires javafx.controls;
    requires javafx.fxml;
    requires javafx.graphics;
    requires javafx.media;
    requires javafx.swing;
    requires javafx.web;
    exports mediaplayerjavafx;
    opens mediaplayerjavafx to javafx.graphics;
}

产生错误

java.nio.file.FileSystemException: C:\Users\John Doe\OneDrive\Desktop\YourLieInAprilTest\Mp3Test.mp3: The process cannot access the file because it is being used by another process.

    at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:92)
    at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
    at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
    at java.base/sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:270)
    at java.base/sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:105)
    at java.base/java.nio.file.Files.delete(Files.java:1141)
    at MotisHarmony/mediaplayerjavafx.JavaFxMp3WavPlayer.deleteMusicFile(JavaFxMp3WavPlayer.java:53)
    at MotisHarmony/mediaplayerjavafx.JavaFxMp3WavPlayer.handle(JavaFxMp3WavPlayer.java:43)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8792)
    at javafx.controls/javafx.scene.control.Button.fire(Button.java:203)
    at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:208)
    at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3897)
    at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1878)
    at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2623)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent(GlassViewEventHandler.java:450)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
    at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:557)
    at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:943)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop(WinApplication.java:184)
    at java.base/java.lang.Thread.run(Thread.java:834)

附加信息

Link to the Mp3 file I used to test. https://drive.google.com/file/d/1CvAafbMviQ7nvKyojnem9GK73LJsD6MJ/view?usp=sharing

I am using JDK 11 and Javafx 17.0.2

System Type: 64-bit operating system, x64-based processor

Processor: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz 2.81 GHz

Windows Edition: Windows 10 Home

感谢@Slaw 为我的问题提供了解决方案。为了解决我的问题,我创建了一个 deletionQueue ArrayList,它将保存我要删除的文件的路径。一旦在 MediaPlayer 上使用 .dispose() ,经过一定时间后,这些文件将被自动删除。