使用jar文件中的字节数组缓存声音

时间:2013-03-31 02:56:16

标签: java stream bytearray javasound getresource

我可以使用标记维基页面中的“播放Clip”解决方案来阅读和播放声音。但是,对于经常播放的声音(例如,快速的激光枪声,脚步声等),每次想要创建新的Clip时,打开流并重新读取文件对我来说很不利。 。所以,我正在尝试将读取文件缓存到byte[]中,然后从缓存中加载它们。

装载部分很简单:

// Get a BAIS.
ByteArrayInputStream bais = new ByteArrayInputStream(cache.get(fileName));

// Convert to an audio stream.
AudioInputStream ais = AudioSystem.getAudioInputStream(bais);

然而,最初将文件内容转换为字节数组证明是一个挑战。问题是我试图从.jar 中包含的文件中读取声音 - 所以使用java.io.File不是一个选项(据我所知),以及各种解决方案我已经看到(下面的链接)不适用。

在我看来,最困难的部分是获取文件的长度来创建字节数组而不使用java.io.File。我可以使用Scanner读取字节,但我需要将它们读入某个数组。我应该使用ArrayList<Byte>吗? (参见下面的“次优示例”。)

所以,我的问题:我可以将嵌入文件读入byte[]以便以后重复访问的最佳方式是什么?

限制

  • 我必须能够访问jar文件中的文件。我认为这限制了我Class.getResourceClass.getResourceAsStream
  • 文件字节应存储在标准byte[]变量中。
  • 我更喜欢这样做,而不会引入不必要的依赖项,例如Guava或Apache Commons。到目前为止,我的整个项目都是使用vanilla Java(JDK6),我想保持这种方式。

我尝试了什么?

我尝试过使用RandomAccessFile,就像这样:

// Get the file.
RandomAccessFile f = new RandomAccessFile(fullPath, "r");

// Create a byte array.
theseBytes = new byte[(int) f.length()];

// Read into the array.
f.read(theseBytes);

// Close the file.
f.close();

// Put in map for later reference.
byteCache.put(fullPath, theseBytes);

但是,显然这仅适用于磁盘引用文件;我收到以下错误:

  

java.io.FileNotFoundException:\ path \ to \ sound \ in \ jar \ file.wav(系统找不到指定的路径)

次优示例

虽然这个示例有效,但我不认为ArrayList是最好的方法,因为不断调整大小等等。

// Get a stream.
InputStream s = clazz.getResourceAsStream(fullPath);

// Get a byte array.
ArrayList<Byte> byteArrayList = new ArrayList<Byte>();

// Create a storage variable.
int last = 0;

// Loop.
while ((last = s.read()) != -1) {
    // Get it.
    byteArrayList.add((byte) last);
}

// Create a byte array.
theseBytes = new byte[byteArrayList.size()];

// Loop over each element.
for (int i = 0; i < theseBytes.length; i++) {
    // Set the byte.
    theseBytes[i] = byteArrayList.get(i);
}

上一页阅读

1 个答案:

答案 0 :(得分:3)

试试这个:

InputStream is = new BufferedInputStream(getClass().getResourceAsStream(name));
ByteArrayOutputStream out = new ByteArrayOutputStream();
for (int b; (b = is.read()) != -1;) {
    out.write(b);
}
byte[] a = out.toByteArray();

其中name.jar中文件的路径。