fatevil
fatevil

Reputation: 47

Check if file with "ftp" url exists using java

please, could anyone tell me, how can i check if file exists on URL where is only FTP protocol? Im using this code:

   public boolean exists(String URLName) throws IOException {
        input = null;
        boolean result = false;
        try {
            input = new URL(URLName).openStream();
            System.out.println("SUCCESS");
            result = true;
        } catch (Exception e) {
            System.out.println("FAIL");
        } finally {
            if (input != null) {
                input.close();
                input = null;
            }
        }
        return result;
    }

It doesnt work when i send there more then one or two, it just sais

    sun.net.ftp.FtpProtocolException: Welcome message: 421 Too many connections (2) from this IP

        at sun.net.ftp.FtpClient.openServer(FtpClient.java:490)
        at sun.net.ftp.FtpClient.openServer(FtpClient.java:475)


at sun.net.www.protocol.ftp.FtpURLConnection.connect(FtpURLConnection.java:270)
    at sun.net.www.protocol.ftp.FtpURLConnection.getInputStream(FtpURLConnection.java:352)
    at java.net.URL.openStream(URL.java:1010)
    at bibparsing.PDFImage.exists(PDFImage.java:168)
    at bibparsing.PDFImage.main(PDFImage.java:189)

It works great when the protocol is HTTP. I mean adresses like:

ftp://cmp.felk.cvut.cz/pub/cmp/articles/chum/Chum-TR-2001-27.pdf ftp://cmp.felk.cvut.cz/pub/cmp/articles/martinec/Kamberov-ISVC2006.pdf and something like that

Upvotes: 1

Views: 2208

Answers (1)

Peter Walser
Peter Walser

Reputation: 15706

The problem here is that this method isn't thread safe; if two threads use this method simultaneously one can overwrite the instance variable named input, causing the other thread to not closing the connection it opened (and closing either nothing, or the connection opened by the other thread).

This is easily fixed, by making the input variable local:

InputStream input=null;

Code style: within a method, you can return the result as soon as you know it. Beginners often declare the variables first, then execute the logic and return the result at the end of the method. You can save a lot of code and complexity by

  • declaring variables as late as possible (when you first need them)
  • declaring as few variables as necessary (readability is always a good reason to add variables, but less variables means less complexity)
  • returning as soon as you know the result (reducing paths through your code, and thus reducing complexity)

The code can be simply written as:

public static boolean exists (String urlName) throws IOException {
    try {
        new URL(urlName).openStream().close();
        return true;
    } catch (IOException e) {
        return false;
    }
}

Upvotes: 3

Related Questions