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

标签 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[] 的最佳方式是什么?以便以后重复访问?

限制

  • 我必须能够访问 jarfile 中的文件。我相信这将我限制为 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 (The system cannot find the path specified)

次优示例

虽然这个例子有效,但我不认为 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);
}

以前的阅读

最佳答案

试试这个:

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 中文件的路径。

关于java - 使用 jar 文件中的字节数组缓存声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15725871/

相关文章:

c# - 在 Java 中读取 C# 字节数组

java - Jasperreports 引擎 JRRuntimeException on report().show

java - 想要在Java中的特定时间后发送邮件

c++ - 如何将内存块的指针转换为标准流

algorithm - Scala 堆大小异常中的 Euler 23

actionscript-3 - 如何将声音从库中引入ByteArray(然后播放该ByteArray)?

c# - 将字节数组重新解释为结构数组

java - AMQP 异步监听器仅在事件发生后才开始监听消息

java - 递归解压缩字符串

node.js - Stream.Transform 在完成输出之前接受新输入