David
David

Reputation: 551

Determine CLASSPATH resource file size

The Question

Is it possible to determine the size of an arbitrary classpath resource? Here's a hypothetical build below (full disclosure: I'm not google). In this case I want to obtain the size of icon.png.

I know I can create a Path/File from this resource using it's URI (from the classpath URL) and get it's size.

Files.size(Path.get(ClassLoader.getSystemResource(iconPath).toURI()))

But it's my understanding this won't work when I deploy this in a JAR or use an AOT compilation tool such as Excelsior JET.

Note: in both these scenarios (Excelsior or the JAR) I can load icon.png just fine.

Just to clarify. My goal is not to obtain a file from a given resource! The goal is to obtain the size of the resource. The above is just an example of a broken solution.

The Reason

To obtain accurate progress information while loading many resources during run time.

Equate the current progress from the current amount of bytes processed to the total amount of bytes to be processed.

TL;DR I just need someone to tell me that this is not possible so I can come up with a different solution.

Upvotes: 3

Views: 2133

Answers (1)

David
David

Reputation: 551

Bingo. Found an answer and wanted to share it for anyone else trying to do the same thing.

The trick is to get the content length from the URL provided from the class loader. Looks a little something like this:

ClassLoader.getSystemResource(iconPath).openConnection().getContentLength();

I guess this means the JRE provides the size of the resource in the content-length header field of the URL connection.

EDIT

  • According to EJP from the comments:

    • It provides it, but not in a header. Resource URLs are a magic system: URL type which is backed by a URLConnection subclass that implements getContentLength() by looking at the actual resource.

I went ahead and gave the other available header queries from URL connection a go also. That is:

  • getContentLength
  • getContentEncoding
  • getContentType
  • getDate
  • getExpiration
  • getLastModified

Here's my results:

getContentLength:           2817
getContentEncoding:         null
getContentType:             image/png
getDate:                    0
getExpiration:              0
getLastModified:            1456358464819

It looks like the only useful information (which I'm more then content with) is the content length, type and modified.

I went ahead and confirmed that this works with both Executable JARs and Excelsior JET 11 built applications.

Note: this was tested on a Windows 10 Home machine running SE 1.8.0_72. In other words, I'm not sure if the header information is available on other operating systems or lower versions of Java.

Nevertheless, Cheers.

Upvotes: 3

Related Questions