【问题标题】:How do I determine whether a path is a local file or not如何确定路径是否为本地文件
【发布时间】:2011-07-04 18:50:13
【问题描述】:

仅给定一个字符串形式的位置,是否有可靠的方法来确定这是本地文件(例如 /mnt/sdcard/test.jpg)还是远程资源(例如 http://www.xyz.com/test.jpg)?

使用 Uri.parse 将其转换为 Uri 似乎并没有给我任何指示文件位置的信息。

我真的不想在字符串中查找 //!

【问题讨论】:

  • 正在检查 www、http 或 .com?
  • String str="本地文件" or "远程文件" then if((str.indexOf("http")||str.indexOf("www"))==-1){/ /local file}else{//remote file},我觉得可以帮到你
  • @Gens & @riser - 还有一些其他的组合也必须包括在内。如果协议既不是 http(例如 https)也不是子域 www,这将不起作用。虽然我希望有一种核心方法可以为我做到这一点,但我想我可能不得不采用正则表达式解决方案,例如下面的@Penkov Vladimir 建议

标签: java android


【解决方案1】:

您也可以通过android.webkit.URLUtil 类检查

URLUtil.isFileUrl(file) || URLUtil.isContentUrl(file)

或上述类的任何其他成员函数。 建议在其之前进行验证

URLUtil.isValidUrl(file)

【讨论】:

  • 这个应该接受,这是最简单最优雅的方式!
  • 但是URLUtil.isFileUrl("/mnt/sdcard/somefile.txt") 返回false
  • 不适用于此路径/storage/emulated/0/Botad News/Images/welcome to botad,名字就够了.png
  • 静态最终字符串 FILE_BASE = "file://"; code public static boolean isFileUrl(String url) { return (null != url) && (url.startsWith(FILE_BASE) && !url.startsWith(ASSET_BASE) && !url.startsWith(PROXY_BASE)); }`
  • 这个答案已经过时了,因为我们有了新的 FileProvider api,并且本地文件可能存在于内容 URI 中。 isFileUrl() 不检查 url 是否以 content: 开头
【解决方案2】:

uri 格式是

<protocol>://<server:port>/<path>

本地文件有:

file:///mnt/...

或者只是

 /mnt

所以如果字符串以

开头
\w+?://

这不是 file:// 那么这是 url

【讨论】:

  • android.resource:// 呢?
【解决方案3】:

我也遇到了同样的问题,并尝试使用 Penkov Vladimir 解决方案,但它不起作用,因为 Uri 具有同样不是远程资源的“内容”架构。

我使用了以下代码,效果很好。

List<Uri> urls = new ArrayList<>();
List<Uri> locals = new ArrayList<>();
for (Uri uri : uris) {
    if (uri.getScheme() != null && (uri.getScheme().equals("content") || uri.getScheme().equals("file"))) {
        locals.add(uri);
    } else {
        urls.add(uri);
    }
}

【讨论】:

    【解决方案4】:

    为了避免硬编码:

    import java.io.File;
    import java.net.MalformedURLException;
    import java.net.URI;
    import java.net.URL;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    public class Test {
    
      public static void main( String args[] ) throws Exception {
        final String[] inputs = {
          "/tmp/file.txt",
          "http://www.stackoverflow.com",
          "file:///~/calendar",
          "mailto:java-net@java.sun.com",
          "urn:isbn:096139210x",
          "gopher://host.com:70/path",
          "wais://host.com:210/path",
          "news:newsgroup",
          "nntp://host.com:119/newsgroup",
          "finger://user@host.com/",
          "ftp://user:password@host.com:2121/",
          "telnet://user:password@host.com",
          "//localhost/index.html"
        };
    
    
        for( final String input : inputs ) {
          System.out.println( "---------------------------------------------" );
    
          final String protocol = getProtocol( input );
          System.out.println( "protocol: " + protocol );
    
          if( "file".equalsIgnoreCase( protocol ) ) {
            System.out.println( "file    : " + input );
          }
          else {
            System.out.println( "not file: " + input );
          }
        }
      }
    
      /**
       * Returns the protocol for a given URI or filename.
       *
       * @param source Determine the protocol for this URI or filename.
       *
       * @return The protocol for the given source.
       */
      private static String getProtocol( final String source ) {
        assert source != null;
    
        String protocol = null;
    
        try {
          final URI uri = new URI( source );
    
          if( uri.isAbsolute() ) {
            protocol = uri.getScheme();
          }
          else {
            final URL url = new URL( source );
            protocol = url.getProtocol();
          }
        } catch( final Exception e ) {
          // Could be HTTP, HTTPS?
          if( source.startsWith( "//" ) ) {
            throw new IllegalArgumentException( "Relative context: " + source );
          }
          else {
            final File file = new File( source );
            protocol = getProtocol( file );
          }
        }
    
        return protocol;
      }
    
      /**
       * Returns the protocol for a given file.
       *
       * @param file Determine the protocol for this file.
       *
       * @return The protocol for the given file.
       */
      private static String getProtocol( final File file ) {
        String result;
    
        try {
          result = file.toURI().toURL().getProtocol();
        } catch( Exception e ) {
          result = "unknown";
        }
    
        return result;
      }
    }
    

    输出:

    ---------------------------------------------
    protocol: file
    file    : /tmp/file.txt
    ---------------------------------------------
    protocol: http
    not file: http://www.stackoverflow.com
    ---------------------------------------------
    protocol: file
    file    : file:///~/calendar
    ---------------------------------------------
    protocol: mailto
    not file: mailto:java-net@java.sun.com
    ---------------------------------------------
    protocol: urn
    not file: urn:isbn:096139210x
    ---------------------------------------------
    protocol: gopher
    not file: gopher://host.com:70/path
    ---------------------------------------------
    protocol: wais
    not file: wais://host.com:210/path
    ---------------------------------------------
    protocol: news
    not file: news:newsgroup
    ---------------------------------------------
    protocol: nntp
    not file: nntp://host.com:119/newsgroup
    ---------------------------------------------
    protocol: finger
    not file: finger://user@host.com/
    ---------------------------------------------
    protocol: ftp
    not file: ftp://user:password@host.com:2121/
    ---------------------------------------------
    protocol: telnet
    not file: telnet://user:password@host.com
    ---------------------------------------------
    Exception in thread "main" java.lang.IllegalArgumentException: Relative context: //localhost/index.html
        at Test.getProtocol(Test.java:67)
        at Test.main(Test.java:30)
    

    【讨论】:

      【解决方案5】:

      要检查它是否是本地文件,您可以简单地这样做:

      public static boolean isLocalFile(String path) {
              return new File(path).exists();
      }
      

      要检查它是否是一个 url,Cameron Ketcham 的答案是最好的。

      【讨论】:

        【解决方案6】:

        基于answer by Penkov Vladimir,这是我使用的确切Java代码:

        String path = "http://example.com/something.pdf";
        if (path.matches("(?!file\\b)\\w+?:\\/\\/.*")) {
            // Not a local file
        }
        

        RegExr一起观看直播

        【讨论】:

        • /tmp/file.txtfile:///~/calendar do not validate 作为文件。
        • 没错,因为上面的正则表达式匹配 remote 文件。也许我们需要另一个正则表达式来实际确定“非远程文件”是否毕竟是一个文件(参见 urn:isbn:096139210x)。但是,如果您现在已经在处理文件位置,那么这个正则表达式应该可以解决问题
        猜你喜欢
        • 2014-06-27
        • 2014-04-27
        • 2011-09-06
        • 2017-05-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-11
        • 2017-08-30
        相关资源
        最近更新 更多