Почему getResourceAsStream() не работает в файлах JAR?

У меня есть следующий код в статическом методе:

clips.open(AudioSystem.getAudioInputStream(Sound.class.getResourceAsStream("folder/sound.wav")));

Кроме того, folder находится в том же каталоге, что и Sound.java. Когда я запускаю программу в Eclipse, звук воспроизводится. Однако, когда я экспортирую файл в файл JAR, звук больше не воспроизводится.

Если я изменю getResourceAsStream() на getResource(), и Eclipse, и файл JAR воспроизведут звук. Почему это происходит? Я читал, и многие люди предполагают, что getResourceAsStream() просто не работает в файлах JAR. Так ли это, и если да, то почему нет?


person null    schedule 07.06.2015    source источник
comment
Я сомневаюсь, что ваш getResource работает по-другому в случае с JAR.   -  person Sotirios Delimanolis    schedule 07.06.2015
comment
Неа. С getResource() файл JAR правильно воспроизводит звук. Другие, похоже, также наблюдают это, например здесь и здесь.   -  person null    schedule 07.06.2015
comment
Интересные ссылки. Я замечаю, что в этих темах они не доводят до конца установление истинной причины, почему один работает, а другой нет. Я подозреваю, что это связано с использованием InputStream или нет (согласно моему ответу). Но также имеет смысл заявить, что жизнь слишком коротка и если у вас есть что-то, что работает, двигайтесь дальше!   -  person Phil Freihofner    schedule 08.06.2015


Ответы (1)


Я подозреваю, что проблема в том, что Class.getResourceAsStream(String) возвращает InputStream, а Class.getResource(String) возвращает URL-адрес. Таким образом, в первом случае мы фактически используем

AudioSystem.getAudioInputStream(InputStream inputStream) 

а во втором случае с помощью

AudioSystem.getAudioInputStream(URL url).

Почему это важно? Я думаю, что основная проблема заключается в том, что когда InputStream является параметром, тесты пометки/сброса выполняются для вашего аудиофайла, и он терпит неудачу. Если в качестве параметра используется URL, этот тест не выполняется. Вы можете проверить API для AudioSystem.getAudioInputStream, чтобы подтвердить то, о чем я здесь сообщаю.

Вы получаете сообщение об ошибке при сбое getResourceAsStream? Случайно ли упоминается ошибка теста отметки/сброса? Если вы получаете другое сообщение об ошибке, возможно, это неправильный ответ, и происходит что-то еще.

person Phil Freihofner    schedule 08.06.2015
comment
Нет ошибки отметки/сброса. Однако при печати трассировки стека есть несколько FileNotFoundException. Впрочем, это ожидаемо. Моя программа работает так: пользователь выбирает папку, содержащую файлы, и эти файлы загружаются в программу. Поэтому могут быть случаи, когда у пользователя нет определенного файла (который не требуется), и это не должно быть проблемой. Кроме того, я получаю FileNotFoundException как для getResource(), так и для getResourceAsStream(), так что это не должно быть причиной того, что звуки не воспроизводятся с getResourceAsStream(). - person null; 08.06.2015
comment
1) Можете ли вы изолировать сообщение об ошибке для неисправного экземпляра? Другими словами, попробуйте загрузить файл, который, как вы знаете, существует и не должен вызывать сообщение о том, что он не найден, и ошибка возникает, когда вы используете getResourceAsStream, но не GetResource? 2) Однажды у меня была ситуация, когда на этапе InputStream произошел сбой (из-за пометки/сброса), но вызывающий метод getAudioInputStream() отреагировал на этот сбой, сообщив о нем как о ненайденном файле, вместо того, чтобы передать ошибку нижнего уровня. Информация, которую вы мне только что дали, не полностью исключает такую ​​возможность, хотя истинная причина остается загадкой. - person Phil Freihofner; 08.06.2015