如何判断一个字符串路径是Web URL还是基于文件的?

10

我有一个文本字段从用户那里获取位置信息(字符串类型)。它可以基于文件目录(例如 C:\directory)或 Web URL(例如 http://localhost:8008/resources)进行。系统将从该位置读取一些预定的元数据文件。

鉴于输入字符串,我如何有效地检测路径位置的性质是否是基于文件还是Web URL。

到目前为止我已经尝试过。

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.

我仍在努力寻找处理这两种情况的最佳方法。 :-(

基本上,我不想使用前缀 http://https:// 显式地检查路径。

有没有一种优雅而恰当的方法来处理这个问题?

4个回答

7
您可以检查location是否以http://https://开头:
String s = location.trim().toLowerCase();
boolean isWeb = s.startsWith("http://") || s.startsWith("https://");

或者您可以使用 URI 类代替 URLURI 不会像 URL 类一样抛出 MalformedURLException 异常:

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

虽然new URI()在位置中使用反斜杠时也可能抛出URISyntaxException。最好的方法是使用前缀检查(我的第一个建议)或创建一个URL并捕获MalformedURLException,如果抛出此异常,则知道它不可能是一个有效的web url。


我刚刚编辑了问题,我正在寻找除手动检查之外的其他方法。 - bLaXjack
增加了另一种不使用前缀检查的方法。 - icza
我有点像URI的例子,但不幸的是就像你所说的,在文件位置中使用反斜杠会抛出异常。 - bLaXjack

2

如果你认为try/catch语句对于代码的优化是“优雅”的,那么这里有一种更具体的方式:

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");
    }
}

这样做可以获得自动的URL语法检查,如果失败了,还会检查文件是否存在。

这不错,但是它还需要一些补丁代码,我认为你也需要捕获 URISyntaxException。 - bLaXjack

1
你可以尝试:

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;
    }
}

请注意,如果URL无效或不是HTTP/HTTPS URL,则此函数将返回false。一个格式错误的URL并不一定是一个实际的文件名,而一个良好的文件名可能指的是一个不存在的文件,因此请与您的文件存在检查一起使用。

0
public boolean urlIsFile(String input) {
    if (input.startsWith("file:")) return true;
    try { return new File(input).exists(); } catch (Exception e) {return false;}
}

这是最好的方法,因为它无需麻烦,并且如果您有文件引用,它将始终返回true。例如,其他解决方案不能涵盖可用的众多协议方案,如ftp、sftp、scp或任何未来的协议实现。因此,这个方法适用于所有用途和目的;但前提是文件必须存在,如果不是以文件协议开头,则不行。

如果您根据函数名称查看其逻辑,您应该理解,对于不存在的直接路径查找返回false并不是一个错误,那就是事实。


如果第一次尝试失败,您应该通过文件名验证器进行微调,以便知道是否可以使用所提供的输入创建文件,或者最好直接失败。但在unix系统上,网络协议不会作为文件名进行验证。作者不确定Java的File类是否接受file:协议作为输入。 - Hypersoft Systems
感谢您的编辑@blaXjack,我不知道最终返回将胜过尝试返回。[好东西要知道!] (https://dev59.com/tnVD5IYBdhLWcg3wKoSH#65362) - Hypersoft Systems

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接