javasoundタグ wiki ページの「Playing a 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.getResource
またはに制限すると信じていますClass.getResourceAsStream
。 byte[]
ファイルのバイトは、標準変数に格納する必要があります。- Guava や 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 (指定されたパスが見つかりません)
次善の例
この例は機能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);
}