1

For reference, here is the complete error I am getting:

    java.io.EOFException: Unexpected end of ZLIB input stream
at java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:240)
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:158)
at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:117)
at java.io.FilterInputStream.read(FilterInputStream.java:107)
at com.genomedownloader.Main.FTPGet(Main.java:245)
at com.genomedownloader.Main.access$400(Main.java:28)
at com.genomedownloader.Main$1.call(Main.java:494)
at com.genomedownloader.Main$1.call(Main.java:468)
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.lang.Thread.run(Thread.java:

I just switched my program from using FTP4J as a Java FTP client to Apache FTPClient. I tweaked my download code so that Apache would work, now I get this exception when I try to unzip the *.gz files the program downloads. Here is the relevant code:

 package com.test;

 import org.apache.commons.net.ftp.FTPClient;

 import java.io.*;
 import java.util.zip.GZIPInputStream;

 public class Main {
public static void main(String[] args) throws IOException {
    FTPClient client;
    client = new FTPClient();
    client.connect("ftp.ncbi.nlm.nih.gov");
    client.login("anonymous", "abc123");
    client.setControlKeepAliveTimeout(300 * 60000);
    client.changeWorkingDirectory("/genomes/all/GCF/000/334/875/GCF_000334875.1_ASM33487v1");
    client.retrieveFile("GCF_000334875.1_ASM33487v1_genomic.fna.gz", new BufferedOutputStream(new FileOutputStream(new File(System.getProperty("user.dir") + "\\GenomicFNA.gz"))));
    GZIPInputStream gzipInputStream = new GZIPInputStream(new FileInputStream(System.getProperty("user.dir") + "\\GenomicFNA.gz"));
    OutputStream out = new FileOutputStream(System.getProperty("user.dir") + "\\GenomicFNA.fsa");
    byte[] buf = new byte[1024];
    int len;
    while ((len = gzipInputStream.read(buf)) > 0) {
        out.write(buf, 0, len);
    }
    gzipInputStream.close();
    out.close();
    client.logout();
    client.disconnect();
}
}

What I can't figure out for the life of me is WHY the code works with FTP4J but then fails with Apache, despite the code using nothing from Apache nor FTP4j libraries... Run the above code with Apache commons net, and it should work. (Work as in give the error at the top)

ragoolaman
  • 11
  • 1
  • 4
  • Sorry, I derped, the errors are happening specifically at the while((len = gzipInputStream.read(buf)) > 0) lines, all three/four places they are. – ragoolaman Jul 07 '17 at 17:25
  • Create a [Minimal, Complete, and Verifiable](https://stackoverflow.com/help/mcve) example, don't dump 1000 LOC on us. – Abhijit Sarkar Jul 07 '17 at 17:42
  • Apologies, took me a minute to figure out what you meant, I have made a standalone example showing it – ragoolaman Jul 07 '17 at 18:08
  • Possible duplicate of [Exception: Unexpected end of ZLIB input stream](https://stackoverflow.com/questions/24531089/exception-unexpected-end-of-zlib-input-stream) – Abhijit Sarkar Jul 07 '17 at 18:09
  • Are you referring to the outputstream called "out" or the one the file is downloaded with? I don't quite follow where to put the close. I don't get from that post where to put the close() in relation to my write while loop – ragoolaman Jul 07 '17 at 18:13
  • How many `Closeable` streams are there in the above code? – Abhijit Sarkar Jul 07 '17 at 18:15
  • Two not including the FTPClient – ragoolaman Jul 07 '17 at 18:16
  • Wait, does the close not purge the internal data, as in, can I read from something after closing it from input? If that is the case, apologies on my obliviousness, and inability to code properly – ragoolaman Jul 07 '17 at 18:16
  • What the other answer says is that you close the `OutputStream` first before creating a `GZIPInputStream` that attempts to read from it. The `FTPClient` should be closed too if it's closeable. – Abhijit Sarkar Jul 07 '17 at 18:18
  • You need a Java 101 resource management. Good luck. – Abhijit Sarkar Jul 07 '17 at 18:18

1 Answers1

0

Change the BufferedOutputStream to separate declaration, and change the FileOutputStream likewise, then flush and close both of them before the GZip declaration. Completed code:

  package com.test;

   import org.apache.commons.net.ftp.FTPClient;

  import java.io.*;
  import java.util.zip.GZIPInputStream;

public class Main {
public static void main(String[] args) throws IOException {
    BufferedOutputStream streamy;
    FileOutputStream stream;
    FTPClient client;
    client = new FTPClient();
    client.connect("ftp.ncbi.nlm.nih.gov");
    client.login("anonymous", "abc123");
    client.setControlKeepAliveTimeout(300 * 60000);
    client.changeWorkingDirectory("/genomes/all/GCF/000/334/875/GCF_000334875.1_ASM33487v1");
    client.retrieveFile("GCF_000334875.1_ASM33487v1_genomic.fna.gz", streamy = new BufferedOutputStream(stream = new FileOutputStream(new File(System.getProperty("user.dir") + "\\GenomicFNA.gz"))));
    stream.flush();
    streamy.flush();
    stream.close();
    streamy.close();
    client.logout();
    client.disconnect();
    GZIPInputStream gzipInputStream = new GZIPInputStream(new FileInputStream(System.getProperty("user.dir") + "\\GenomicFNA.gz"));
    OutputStream out = new FileOutputStream(System.getProperty("user.dir") + "\\GenomicFNA.fsa");
    byte[] buf = new byte[1024];
    int len;
    while ((len = gzipInputStream.read(buf)) > 0) {
        out.write(buf, 0, len);
    }
    gzipInputStream.close();
    out.close();

}
}
ragoolaman
  • 11
  • 1
  • 4