4

I'm trying to download .torrent files from the internet. Some of the files online are compressed (gzipped) format. I know I can unzip the files with the following code:

    try (InputStream is = new GZIPInputStream(website.openStream())) {
        Files.copy(is, Paths.get(path));
        is.close();
    }

but some of the .torrent files are not compressed and I therefore get the error message:

java.util.zip.ZipException: Not in GZIP format

I'm dealing with a large database of .torrent files so I can't unzip them 1 by 1 if it is compressed. How do I know whether the .torrent file is compressed or not and only unzip the file if it is compressed?

Pseudo Code:

if(file is compressed){
unzip
download
}else{
download

SOLUTION:

    try (InputStream is = new GZIPInputStream(website.openStream())) {
        Files.copy(is, Paths.get(path + "GZIP.torrent"));
        is.close();
    } catch (ZipException z) {
        File f = new File(path + ".torrent");
        FileOutputStream fos = new FileOutputStream(f);
        ReadableByteChannel rbc = Channels.newChannel(website.openStream());
        fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
        fos.close();
    }
Joe
  • 111
  • 3
  • 14
  • 1
    The content type header may reveal whether the file is compressed or not; you can debug the content type by opening a connection from your URL `connection = website.openConnection()` and then printing `connection.getContentType()`. – FThompson Mar 01 '14 at 17:28
  • Please do not edit the question to show a solution but add it as an answer – mmmmmm Mar 01 '14 at 22:24
  • also, it's generally not great practice to rely on an exception being thrown to do some action in your code... if you can detect whether or not it's a gzip'ed file before an exception is thrown, it is much better. looks to me like you could accomplish this with a simple `if (Paths.get(path).contains("GZIP")) { /* handle gzip code /* } else { /* handle non-gzip code */ }` – SnakeDoc Mar 01 '14 at 22:33

1 Answers1

3

You can use a BufferedInputStream. It is likely to be a good idea in any case. This will allow you to mark() the start and attempt to uncompress the data and if it fails, reset() the stream and read it normally. (more efficiently, all GZIP files start with the same two bytes) ;)

All GZIP streams start with bytes 1f 8b http://en.wikipedia.org/wiki/Gzip

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • I was able to just catch a ZipException instead of creating a BufferedInputStream. Thanks for your help anyways. I've updated the code above to help others with the same problem. – Joe Mar 01 '14 at 22:20
  • @user3243085 That won't give you back the bytes it reads and reading the stream twice is a waste. – Peter Lawrey Mar 01 '14 at 22:24
  • Well I'm only 15 and don't think I can learn enough about BufferedInputStreams and bytes in order to finish this program I'm making. I appreciate the help and I'm sure your way is more efficient. – Joe Mar 01 '14 at 22:59
  • @user3243085 I have been programming in Java for almost 15 years. :P – Peter Lawrey Mar 01 '14 at 23:14