10

I have a text field to acquire location information (String type) from User. It could be file directory based (e.g. C:\directory) or Web url (e.g. http://localhost:8008/resouces). The system will read some predetermined metadata file from the location.

Given the input string, how can I detect the nature of the path location whether it is a file based or Web URL effectively.

So far I have tried.

URL url = new URL(location); // will get MalformedURLException if it is a file based.
url.getProtocol().equalsIgnoreCase("http");

File file = new File(location); // will not hit exception if it is a url.
file.exist(); // return false if it is a url.

I am still struggling to find a best way to tackle both scenarios. :-(

Basically I would not prefer to explicitly check the path using the prefix such as http:// or https://

Is there an elegant and proper way of doing this?

bLaXjack
  • 780
  • 2
  • 11
  • 23

4 Answers4

7

You can check if the location starts with http:// or https://:

String s = location.trim().toLowerCase();
boolean isWeb = s.startsWith("http://") || s.startsWith("https://");

Or you can use the URI class instead of URL, URI does not throw MalformedURLException like the URL class:

URI u = new URI(location);
boolean isWeb = "http".equalsIgnoreCase(u.getScheme())
    || "https".equalsIgnoreCase(u.getScheme())

Although new URI() may also throw URISyntaxException if you use backslash in location for example. Best way would be to either use prefix check (my first suggestion) or create a URL and catch MalformedURLException which if thrown you'll know it cannot be a valid web url.

icza
  • 389,944
  • 63
  • 907
  • 827
2

If you're open to the use of a try/catch scenario being "elegant", here is a way that is more specific:

try {
    processURL(new URL(location));
}
catch (MalformedURLException ex){
    File file = new File(location);
    if (file.exists()) {
        processFile(file);
    }
    else {
        throw new PersonalException("Can't find the file");
    }
}

This way, you're getting the automatic URL syntax checking and, that failing, the check for file existence.

John Chesshir
  • 590
  • 5
  • 20
  • this is not bad, but it requires some patchy code as well, i believe u need to catch the URISyntaxException as well. – bLaXjack Aug 26 '17 at 05:24
1

you can try:

static public boolean isValidURL(String urlStr) {
    try {
      URI uri = new URI(urlStr);
      return uri.getScheme().equals("http") || uri.getScheme().equals("https");
    }
    catch (Exception e) {
        return false;
    }
}

note that this will return false for any other reason that invalidates the url, ofor a non http/https url: a malformed url is not necessarily an actual file name, and a good file name can be referring to a non exisiting one, so use it in conjunction with you file existence check.

user1708042
  • 1,740
  • 17
  • 20
0
public boolean urlIsFile(String input) {
    if (input.startsWith("file:")) return true;
    try { return new File(input).exists(); } catch (Exception e) {return false;}
}

This is the best method because it is hassle free, and will always return true if you have a file reference. For instance, other solutions don't and cannot cover the plethora of protocol schemes available such as ftp, sftp, scp, or any future protocol implementations. So this one is the one for all uses and purposes; with the caveat of the file must exist, if it doesn't begin with the file protocol.

if you look at the logic of the function by it's name, you should understand that, returning false for a non existent direct path lookup is not a bug, that is the fact.

bLaXjack
  • 780
  • 2
  • 11
  • 23
  • You should fine tune this, with a file name validator if the you get false on the first try, and you want to know if you can create a file with the input given, or optimally you will simply fail-through. FOR SURE (on unix systems): Web Protocols don't validate as file names. It is unknown to this author if Java's File class Will accept file: protocols as input. – Hypersoft Systems Dec 03 '17 at 17:02
  • Thank you for the edit @blaXjack, did not know that finally return would trump the return from try. [Good stuff to know!](https://stackoverflow.com/a/65362/3370790) – Hypersoft Systems Dec 05 '17 at 04:26