Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if the path input is URL or Local File

Tags:

c#

private static bool IsLocalPath(string p)
{
  return new Uri(p).IsFile;
}

...or, if you want to include support for certain invalid URIs...

private static bool IsLocalPath(string p)
{
  if (p.StartsWith("http:\\"))
  {
    return false;
  }

  return new Uri(p).IsFile;
}

Example Usage

static void Main(string[] args)
{
  CheckIfIsLocalPath("C:\\foo.txt");
  CheckIfIsLocalPath("C:\\");
  CheckIfIsLocalPath("http://www.txt.com");
}

private static void CheckIfIsLocalPath(string p)
{
  var result = IsLocalPath(p); ;

  Console.WriteLine("{0}  {1}  {2}", result, p, new Uri(p).AbsolutePath);
}

Just using new Uri(yourPath) won't work in all cases.

Comparing various scenarios (via LinqPad).

    var tests = new[] {
        Path.GetTempFileName(),
        Path.GetDirectoryName(Path.GetTempFileName()),
        "http://in.ter.net",
        "http://in.ter.net/",
        "http://in.ter.net/subfolder/",
        "http://in.ter.net/subfolder/filenoext",
        "http://in.ter.net/subfolder/file.ext",
        "http://in.ter.net/subfolder/file.ext?somequerystring=yes",
        Path.GetFileName(Path.GetTempFileName()),
        Path.Combine("subfolder", Path.GetFileName(Path.GetTempFileName())),
    };

    tests.Select(test => {
        Uri u;
        try {
            u = new Uri(test);
        } catch(Exception ex) {
            return new {
                test,
                IsAbsoluteUri = false,
                // just assume
                IsFile = true,
            };
        }

        return new {
            test,
            u.IsAbsoluteUri,
            u.IsFile,
        };
    }).Dump();

Results

Linqpad results of path checking


In case of a malformed path (non-existing path,empty string, null string) Uri(p).IsFile throws an exception. In my opinion is better to use two methods to discern what is what:

private bool PathIsLocalFile(string path)
{
    return File.Exists(path);
}

private bool PathIsUrl(string path)
{
    if (File.Exists(path))
        return false;
    try
    {
        Uri uri = new Uri(path);
        return true;
    }
    catch (Exception)
    {
        return false;
    }
}

//

Microsoft docs: 
public static bool Exists(string path);

Returns: true if the caller has the required permissions and path contains the name of an existing file; otherwise, false. This method also returns false if path is null, an invalid path, or a zero-length string. If the caller does not have sufficient permissions to read the specified file, no exception is thrown and the method returns false regardless of the existence of path. //

Microsoft docs: 
public Uri(string uriString);

Exceptions:

T:System.ArgumentNullException:

uriString is null.

T:System.UriFormatException:

uriString is empty.-or- The scheme specified in uriString is not correctly formed. See System.Uri.CheckSchemeName(System.String).-or- uriString contains too many slashes.-or- The password specified in uriString is not valid.-or- The host name specified in uriString is not valid.-or- The file name specified in uriString is not valid. -or- The user name specified in uriString is not valid.-or- The host or authority name specified in uriString cannot be terminated by backslashes.-or- The port number specified in uriString is not valid or cannot be parsed.-or- The length of uriString exceeds 65519 characters.-or- The length of the scheme specified in uriString exceeds 1023 characters.-or- There is an invalid character sequence in uriString.-or- The MS-DOS path specified in uriString must start with c:\.


Simply set the rule for all remote file, it should (and it must) include the protocol in the URI:

http://
ftp://

and for local file, it can be

file://

for absolute path and no protocol for relative.

Then simple regex could help extracting the right information.