How to load a classpath resource to an array of byte?
Solution 1
Have a look at Google guava ByteStreams.toByteArray(INPUTSTREAM)
, this is might be what you want.
Solution 2
Java 9 native implementation:
byte[] data = this.getClass().getClassLoader().getResourceAsStream("/assets/myAsset.bin").readAllBytes();
Solution 3
Although i agree with Andrew Thompson, here is a native implementation that works since Java 7 and uses the NIO-API:
byte[] data = Files.readAllBytes(Paths.get(this.getClass().getClassLoader().getResource("/assets/myAsset.bin").toURI()));
Solution 4
Take a look at Apache IOUtils - it has a bunch of methods to work with streams
Solution 5
I usually use the following two approaches to convert Resource
into byte[]
array.
1 - approach
What you need is to first call getInputStream()
on Resource
object, and then pass that to convertStreamToByteArray
method like below....
InputStream stream = resource.getInputStream();
long size = resource.getFile().lenght();
byte[] byteArr = convertStreamToByteArray(stream, size);
public byte[] convertStreamToByteArray(InputStream stream, long size) throws IOException {
// check to ensure that file size is not larger than Integer.MAX_VALUE.
if (size > Integer.MAX_VALUE) {
return new byte[0];
}
byte[] buffer = new byte[(int)size];
ByteArrayOutputStream os = new ByteArrayOutputStream();
int line = 0;
// read bytes from stream, and store them in buffer
while ((line = stream.read(buffer)) != -1) {
// Writes bytes from byte array (buffer) into output stream.
os.write(buffer, 0, line);
}
stream.close();
os.flush();
os.close();
return os.toByteArray();
}
2 - approach
As Konstantin V. Salikhov suggested, you could use org.apache.commons.io.IOUtils
and call its IOUtils.toByteArray(stream)
static
method and pass to it InputStream
object like this...
byte[] byteArr = IOUtils.toByteArray(stream);
Note -
Just thought I'll mention this that under the hood toByteArray(...)
checks to ensure that file size is not larger than Integer.MAX_VALUE
, so you don't have to check for this.
Samuel Rossille
Updated on July 09, 2022Comments
-
Samuel Rossille almost 2 years
I know how to get the inputstream for a given classpath resource, read from the inputstream until i reach the end, but it looks like a very common problem, and i wonder if there an API that I don't know, or a library that would make things as simple as
byte[] data = ResourceUtils.getResourceAsBytes("/assets/myAsset.bin")
or
byte[] data = StreamUtils.readStreamToEnd(myInputStream)
for example!
-
Andrew Thompson almost 12 years"it looks like a very common problem" Commonly Java methods will accept an
InputStream
. -
Louis Wasserman almost 12 yearsI think that with Guava, this is more or less
Resources.toByteArray(Resources.getResource(contextClass, resourceName))
? -
Samuel Rossille almost 12 years@AndrewThompson you just prevented me from doing something stupid in this precise case, thank you.
-
Andrew Thompson almost 12 yearsEntered as (alternate) answer. ;)
-
-
Pablo Thiele over 8 yearsGood approach but I think that you means convertStreamToByteArray instead of Steam. :) Nice answer.
-
yunandtidus over 8 yearsmore precisely something as
IOUtils.toByteArray(getClass().getClassLoader().getResourceAsStream("XXX")
-
Simple-Solution over 7 years@PabloRS I've rectified the typo. Ta :)
-
cesAR over 7 yearsThis is useful for me in 2016. I am using the latest version of IOUtils with Maven: https://mvnrepository.com/artifact/commons-io/commons-io/2.5, through the suggestion of @yunandtidus Thanks.
-
Innokenty over 2 yearsMy favourite is
IOUtils.resourceToByteArray("XXX", getClass().getClassLoader())
as it's a tiny bit shorter. -
Joe White over 2 yearsIf I'm running from a JAR, this fails with a FileSystemNotFoundException. I can get it to work by registering the JAR as a filesystem using FileSystems.newFileSystem, but I have to do that for each JAR I want to read resources from.
-
ltlBeBoy about 2 years@JoeWhite Depending on the environment it may be required to remove the leading slash. E.g. in newer versions of Payara application server the class loader is able to find the resources only if it's a relative path.