我可以使用javasound標記wiki頁面上的「播放Clip
」解決方案來讀取和播放聲音。但是,對於頻繁播放的聲音(例如,快速激光槍聲,腳步聲等),每當您想要創建新的Clip
時,我都會打開流並重新讀取文件。所以,我試圖將讀取的文件緩存到byte[]
中,隨後從緩存中加載它們。使用jar文件中的字節數組緩存聲音
裝載部分很簡單:
// 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.getResource
或Class.getResourceAsStream
。 - 文件字節應存儲在標準的
byte[]
變量中。 - 我寧願這樣做沒有引入不必要的依賴項,如番石榴或Apache Commons。到目前爲止,我的整個項目都是在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);
}
上閱讀
- Answer to "File to byte[] in Java" by Dmitry Mitskevich
- Answer to "Reading a binary file into a single byte array in JAVA" by GregS
- 的javasound標籤wiki頁面
優秀的問題格式! –