Как определить, является ли путь локальным файлом или нет?

Учитывая просто местоположение в виде строки, существует ли надежный способ определить, является ли это локальным файлом (например,/mnt/sdcard/test.jpg) или удаленным ресурсом (например, http://www.xyz.com/test.jpg)?

Преобразование его в Uri с Uri.parse, похоже, не дает мне ничего, чтобы указать, где находится файл.

Я действительно не хочу искать//в строке!

Ответ 1

Формат uri -

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

локальные файлы имеют:

file:///mnt/...

или просто

 /mnt

поэтому, если строка начинается с

\w+?://

и это не файл://то это url

Ответ 2

Вы также можете проверить класс android.webkit.URLUtil

URLUtil.isFileUrl(file)

Ответ 3

У меня также была такая же проблема, и я попытался использовать решение Пенькова Владимира, но это не сработало, потому что у Ури была схема "контента", которая также не является удаленным ресурсом.

Я использовал следующий код, и он отлично работал.

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:[email protected]",
      "urn:isbn:096139210x",
      "gopher://host.com:70/path",
      "wais://host.com:210/path",
      "news:newsgroup",
      "nntp://host.com:119/newsgroup",
      "finger://[email protected]/",
      "ftp://user:[email protected]:2121/",
      "telnet://user:[email protected]",
      "//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:[email protected]
---------------------------------------------
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://[email protected]/
---------------------------------------------
protocol: ftp
not file: ftp://user:[email protected]:2121/
---------------------------------------------
protocol: telnet
not file: telnet://user:[email protected]
---------------------------------------------
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

Основываясь на ответе Пенькова Владимира, это точный код Java, который я использовал:

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

Посмотрите это в прямом эфире с RegExr

Ответ 6

Проверка Fo, если это локальный файл, вы можете просто сделать это:

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

Чтобы проверить, соответствует ли он правильному ответу Кэмерона Кетчама.