我可以使用javasound标签 wiki 页面中的“播放Clip
”解决方案来阅读和播放声音。但是,对于经常播放的声音(例如,快速的激光枪声、脚步声等),每次您想要创建新的. 因此,我试图将读取的文件缓存到 a中,然后从缓存中加载它们。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
. 我可以用 a 读取字节Scanner
,但我需要将它们读入某个数组。我应该使用ArrayList<Byte>
吗?(请参阅下面的“次优示例”。)
所以,我的问题是:我可以将嵌入文件读入以byte[]
供以后重复访问的最佳方式是什么?
限制
- 我必须能够访问 jarfile 中的文件。我相信这将我限制在
Class.getResource
orClass.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
,但由于不断调整大小等,我认为 an 不是最好的方法。
// 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);
}