Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading a GZIP file from a FileChannel (Java NIO)

I need to read/unpack a .gz file given a FileChannel.

I've played around with extracting GZIP archives using GZIPInputStream, but this won't take a FileChannel. I don't have access to the original FileInputStream that the FileChannel was taken from.

If someone could tell me a good way (or at least any way) of reading GZIP from a FileChannel, I would greatly appreciate it.

Adapted from a question on the Sun Oracle forums.

like image 203
Franz Joseph Spiegler Avatar asked Jul 26 '10 14:07

Franz Joseph Spiegler


2 Answers

You could obtain a wrapping InputStream around the FileChannel:

FileChannel fc = ...
GZIPInputStream gis = new GZIPInputStream(Channels.newInputStream(fc));

Channels is in Java SE.

like image 71
Dan LaRocque Avatar answered Oct 24 '22 22:10

Dan LaRocque


Yes, there is a solution. Implementing GZip is fairly simple. You need a Inflater and CRC32, plus reading the header/trailer. Unfortunately java.util.zip.Inflater takes only byte[] which is suboptimal (a direct Buffer would have been times more efficient). Yet, using non-direct buffer and ByteBuffer.array() is an option.

The built in java.util.zip.CRC32 is quite slow and reimplementing it in java is a nice step towards performance. com.jcraft.jzlib offers pure java implementation (almost looks like pure C, though) and it's possible to replace the byte[] w/ direct Buffer. The library is somewhat slower compared to inflater (decomppress) due to too many bounds check and inability to perform so deep inline. Yet, it's faster on compression.

like image 29
bestsss Avatar answered Oct 24 '22 22:10

bestsss