FileNotFoundException выдается только для .mp3, но не для .png

Я разрабатываю игру в 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")); 

и я все еще получаю ту же ошибку.

возможно, потому, что используемая система сборки (IDE, Maven, Gradle,...) не считает файлы .mp3 ресурсами и, следовательно, не копирует их из исходной папки в папку сборки. Обычно код не запускается в папке src (так называемом рабочем каталоге), поэтому он не ищет файлы в src.

user85421 14.06.2024 08:28

Когда-то была такая штука, связанная с обработкой путей, где относительные и абсолютные пути поют... Попробуйте следующее: new File(getClass().getRessource("/audio/QuestOfLegends.mp3"));

David Weber 14.06.2024 08:33

@user85421 user85421 Результат new File(".").getAbsolutePath()C:\Users\...\Testing\., где Testing — это папка моего проекта IntelliJ.

soybean 14.06.2024 08:57

@user85421 user85421 Что вы подразумеваете под «папка ` audio` также должна находиться в каком-то каталоге, указанном в пути к классам»? Я использую getResource для чтения изображения: BufferedImage image = ImageIO.read(Objects.requireNonNull(Main.class.getResource(i‌​magePath))); и это успешно. Однако я использую File file = new File(audioPath);, чтобы открыть аудиофайл.

soybean 14.06.2024 09:17

Я имел в виду «должно быть в каком-то каталоге» — как я уже писал, файлы ресурсов ищутся точно так же, как и файлы .class. Таким образом, каталог audio также должен быть найден в одном из каталогов, перечисленных в пути к классам (действителен только при использовании getResource*(), но теперь я видел, что код использует file = new File(audioPath) - не обращайте внимания на путь к классам - проверьте результат file.toAbsolutePath() (несмотря на использование File и getResource немного сбивает с толку/непоследовательно [если вы действительно не понимаете, что они делают])

user85421 14.06.2024 10:58

поскольку при использовании new File("/audio/...") каталог audio должен находиться в корневом каталоге! При использовании new File("audio/...") каталог audio должен находиться в C:\Users\...\Testing\ (поскольку это был результат new File(".").toAbsolutePath())

user85421 14.06.2024 11:03
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
6
77
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Использовать 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);
        }
    }
}

Другие вопросы по теме