Я разрабатываю игру в Swing, в которой я хотел бы использовать как аудио, так и графические ресурсы. Моя проблема в том, что хотя открытие изображений .png работает нормально, открытие моего файла .mp3 всегда выдает FileNotFoundException
, а file.exists()
возвращает false
.
Кажется, ничего не работает. Я исследовал проблему, рассмотрел аналогичный вопрос, поигрался с добавлением и удалением '/' из пути к файлу, сменой каталога mp3, создал новый проект IntelliJ, перезагрузил компьютер и попытался открыть файл . вместо этого wav-файл, но безуспешно.
Вот упрощенная версия моего кода, в которой я пытаюсь успешно прочитать изображение Baker.png
и безуспешно прочитать аудиофайл QuestOfLegends.mp3
.
Main.java
import javax.imageio.ImageIO;
import javax.sound.sampled.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Objects;
public class Main {
public static void main(String[] args) {
String imagePath = "/images/Baker.png";
String audioPath = "/audio/QuestOfLegends.mp3";
System.out.println("The absolute path of this class is: " + new File(".").getAbsolutePath());
System.out.println("The audio package is a directory?: " + new File("/audio").isDirectory());
System.out.println("The images package is a directory?: " + new File("/images").isDirectory());
try {
BufferedImage image = ImageIO.read(Objects.requireNonNull(Main.class.getResource(imagePath)));
System.out.println("Image read successful.");
} catch (IOException e) {
System.out.println("Image read failed.");
}
try {
File file = new File(audioPath);
if (!file.exists()) {
throw new Exception("File does not exit at "+ audioPath);
} else {
AudioInputStream audioInput = AudioSystem.getAudioInputStream(file);
Clip clip = AudioSystem.getClip();
clip.open(audioInput);
clip.start();
clip.loop(Clip.LOOP_CONTINUOUSLY);
}
} catch (Exception e) {
System.out.println("Read failed");
throw new RuntimeException(e);
}
}
}
Вот моя иерархия каталогов .
Я попробовал использовать:
File file = new File(Main.class.getResource("/audio/QuestOfLegends.mp3"));
и я все еще получаю ту же ошибку.
Когда-то была такая штука, связанная с обработкой путей, где относительные и абсолютные пути поют... Попробуйте следующее: new File(getClass().getRessource("/audio/QuestOfLegends.mp3"));
@user85421 user85421 Результат new File(".").getAbsolutePath()
— C:\Users\...\Testing\.
, где Testing — это папка моего проекта IntelliJ.
@user85421 user85421 Что вы подразумеваете под «папка ` audio` также должна находиться в каком-то каталоге, указанном в пути к классам»? Я использую getResource
для чтения изображения: BufferedImage image = ImageIO.read(Objects.requireNonNull(Main.class.getResource(imagePath)));
и это успешно. Однако я использую File file = new File(audioPath);
, чтобы открыть аудиофайл.
Я имел в виду «должно быть в каком-то каталоге» — как я уже писал, файлы ресурсов ищутся точно так же, как и файлы .class
. Таким образом, каталог audio
также должен быть найден в одном из каталогов, перечисленных в пути к классам (действителен только при использовании getResource*()
, но теперь я видел, что код использует file = new File(audioPath)
- не обращайте внимания на путь к классам - проверьте результат file.toAbsolutePath()
(несмотря на использование File
и getResource
немного сбивает с толку/непоследовательно [если вы действительно не понимаете, что они делают])
поскольку при использовании new File("/audio/...")
каталог audio
должен находиться в корневом каталоге! При использовании new File("audio/...")
каталог audio
должен находиться в C:\Users\...\Testing\
(поскольку это был результат new File(".").toAbsolutePath()
)
Использовать File file = new File(Main.class.getResource("/audio/QuestOfLegends.mp3"));
неправильно! Должен быть
InputStream in = Main.class.getResourceAsStream("/audio/QuestOfLegends.mp3");
Ресурсы развертываются вместе с вашим приложением, обычно внутри jar, поэтому они больше не являются файлами в файловой системе.
Ниже показано это, а также некоторые дополнительные наблюдения по исходному коду:
import javax.imageio.ImageIO;
import javax.sound.sampled.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.util.Objects;
public class Main {
public static void main(String[] args) {
String imagePath = "/images/Baker.png";
String audioPath = "/audio/QuestOfLegends.wav"; // MP3 is not supported out of the box
System.out.println("The absolute path of this class is: " + "Wherever it was compiled to");
System.out.println("The audio package is a directory?: " + "No - it's a resource folder");
System.out.println("The images package is a directory?: " + "No - it's a resource folder");
try {
BufferedImage image = ImageIO.read(Objects.requireNonNull(Main.class.getResource(imagePath)));
System.out.println("Image read successful.");
} catch (IOException e) {
System.out.println("Image read failed.");
}
try (InputStream in = Objects.requireNonNull(Main.class.getResourceAsStream(audioPath))) {
AudioInputStream audioInput = AudioSystem.getAudioInputStream(in);
Clip clip = AudioSystem.getClip();
clip.open(audioInput);
clip.start();
clip.loop(Clip.LOOP_CONTINUOUSLY);
// Clip will start in its own thread so prevent the main thread from exiting right away
Thread.sleep(4000);
} catch (Exception e) {
System.out.println("Read failed");
throw new RuntimeException(e);
}
}
}
возможно, потому, что используемая система сборки (IDE, Maven, Gradle,...) не считает файлы
.mp3
ресурсами и, следовательно, не копирует их из исходной папки в папку сборки. Обычно код не запускается в папкеsrc
(так называемом рабочем каталоге), поэтому он не ищет файлы вsrc
.