Java 从我的包中读取声音的路径

Java 从我的包中读取声音的路径,java,audio,clip,Java,Audio,Clip,我有一个儿子班,负责加载和播放声音。还有一个adhd类,它包含主类,并使用这个子类 我所有的类都在包“adhd”中,我在罐子里的声音是这样的:1.wav在罐子里的SoundN中。(ADHD.jar/SoundN/1.wav) 当我在Eclipse中运行代码时,它可以工作,但当我运行jar时,它不能工作。对我来说,保持声音“加载”是很重要的,因为我需要我的程序快速读取声音,因为我正在使用计时器。你建议我做什么 下面是我的类Sons的代码,它在Singleton实例中加载声音 儿子 package

我有一个儿子班,负责加载和播放声音。还有一个adhd类,它包含主类,并使用这个子类

我所有的类都在包“adhd”中,我在罐子里的声音是这样的:1.wav在罐子里的SoundN中。(ADHD.jar/SoundN/1.wav)

当我在Eclipse中运行代码时,它可以工作,但当我运行jar时,它不能工作。对我来说,保持声音“加载”是很重要的,因为我需要我的程序快速读取声音,因为我正在使用计时器。你建议我做什么

下面是我的类Sons的代码,它在Singleton实例中加载声音

儿子

package adhd;

import java.io.File; 
import java.io.IOException; 
import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioInputStream; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.DataLine; 
import javax.sound.sampled.FloatControl; 
import javax.sound.sampled.LineUnavailableException; 
import javax.sound.sampled.SourceDataLine; 
import javax.sound.sampled.UnsupportedAudioFileException;
import java.applet.Applet;
import java.applet.AudioClip;
import java.net.URL;

public class Sons {
    private static String PATH=null;
    private static Sons instance;
    private final Map<String, Clip> sons;
    private boolean desactive;

    Sons(String path) {
        PATH = path;
        sons = new HashMap<String, Clip>();
    }


    public void load(String nom) throws UnsupportedAudioFileException, IOException, LineUnavailableException {
        Clip clip = AudioSystem.getClip();
        clip.open(AudioSystem.getAudioInputStream(getClass().getResourceAsStream(PATH + nom)));
        sons.put(nom, clip);
    }


    public void play(String son) {
        if(!desactive) try {
            Clip c = getSon(son);
            c.setFramePosition(0);
            c.start();
        } catch(Exception e) {
            System.err.println("Impossible to play the sound " + sound);
            desactive = true;
        }
    }
}
这里还有一张这棵树的照片


现在,由于出现了异常消息,我们知道了问题的实质。问题不在于声音无法加载或在罐子中找不到。问题在于,正如所说:

这些解析器必须能够标记流,读取足够的数据以确定它们是否支持流,如果不支持,则将流的读取指针重置到其原始位置。如果输入流不支持这些操作,此方法可能会因IOException而失败

从jar加载资源时,
Class.getResourceAsStream()
返回的流不支持这些操作。因此,您可以将输入流中的所有内容读取到内存中的字节数组中,从该字节数组创建一个
ByteArrayInputStream
,并将该流传递到
AudioSystem.getAudioInputStream()


如果加载内存中的所有内容都不是一个选项,因为声音很长(但我想你不会把它放在罐子里),那么你可以将它写入一个临时文件,然后将一个FileInputStream传递给
AudioSystem.getAudioInputStream()

显然,路径取决于声音文件的位置。如果你不说,我们怎么知道?没有一条神奇的道路能找到“你的包裹之外”的一切,不管这意味着什么。我只是在等你给我这条道路的开始。假设我的文件在主项目文件夹中。也许我可以告诉你我为什么要问。因为当我想访问我的类包中“sounds”文件夹中的sounds时,我必须编写“/sounds/1.wav”。我需要这个罐子来读取我的声音,所以我被告知把它们放在一个源文件夹中。因此,当我这样做时,我有一个名为“src/sounds”的文件夹,它本身就在项目文件夹中。但是我找不到如何访问它,甚至找不到如何访问项目文件夹中的声音,项目的根目录。Class.getResourceAsStream()使用类路径加载资源。它不能加载目录或jar之外的、不在类路径中的任何内容。如果声音位于类路径中的目录/jar中,则使用中描述的规则加载它。否则,请使用文件IO。问题是我确实需要使用此方法,因为我想在实例中加载声音,以便在程序中读取它们(否则会出现错误,因为我使用的计时器每0.5秒读取一次声音)。或者,我该如何让我的罐子读取软件包中的声音?有解决办法吗?(我可以在Eclipse中读取它们,但在运行jar时无法读取)。您有关于这两个选项的示例吗?这实际上是我第一次用java处理声音,这与声音无关。读取输入流的所有字节,然后创建ByteArrayInputStream。阅读javadoc和javaio教程。通过示例我能更好地理解,这就是为什么我要问这个问题。这是我必须做的吗?如果你说的是答案中的代码,那么是的。
public static void main(String[] args) {

    Sons sonN= new Sons("/SoundN/");

    try {
        sonN.load("1.wav");
    } catch (UnsupportedAudioFileException | IOException
            | LineUnavailableException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    sonN.play("1.wav");
}