Sound caching using byte arrays from jar file

I can read and play sounds using the “Play a Clipsolution from the javasound wiki page. However, for sounds that are often played (for example, the sound of a fast laser gun, step, etc.), it seems to me that I open streams and re-read files every time you want to create a new Clip . So, I'm trying to cache the read files in byte[] and subsequently load them from the cache.

The boot part is simple:

 // Get a BAIS. ByteArrayInputStream bais = new ByteArrayInputStream(cache.get(fileName)); // Convert to an audio stream. AudioInputStream ais = AudioSystem.getAudioInputStream(bais); 

However, getting the file contents into a byte array initially is a problem. The problem is that I am trying to read sounds from a file included in .jar - therefore using java.io.File not an option (as I understand it), and the various solutions that I have seen (links below) are not applied.

It seems to me that the hardest part is getting the length of the file to create an array of bytes without using java.io.File . I can read bytes with Scanner , but I need to read them in some kind of array. Should I use an ArrayList<Byte> ? (See "Suboptimal Example" below.)

So my question is: What is the best way to read the embedded file in byte[] for re-access later?

Limitations

  • I must have access to files in jarfile. I believe this limits me to Class.getResource or Class.getResourceAsStream .
  • File bytes must be stored in the standard variable byte[] .
  • I would rather do this without introducing unnecessary dependencies like Guava or Apache Commons. My whole project is still in vanilla Java (JDK6), and I would like to save it that way.

What have i tried?

I tried using RandomAccessFile , for example:

 // 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); 

However, apparently this only works for a file with a disk file; I get the following error:

java.io.FileNotFoundException: \ path \ to \ sound \ in \ jar \ file.wav (the system cannot find the path specified)

Suboptimal example

Although this example works, I don't think ArrayList is the best way to do this due to constant resizing, etc.

 // 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); } 

Previous reading

+4
source share
1 answer

Try the following:

 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(); 

where name is the path to the file in .jar .

+3
source

All Articles