检查路径输入是URL还是本地文件

时间:2010-03-27 06:51:10

标签: c#

我在xmldataprovider工作,我们有配置值“source”这个值可能是本地文件或网址 喜欢

  

c:\ data \ test.xml --absolute   data \ test.xml --relative

     

或url http:\ mysite \ test.xml

我如何在代码中确定所有这些情况 我正在工作c#

5 个答案:

答案 0 :(得分:31)

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

...或者,如果您想包含对某些无效URI的支持......

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

  return new Uri(p).IsFile;
}

使用示例

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

答案 1 :(得分:2)

仅使用new Uri(yourPath)并不适用于所有情况。

比较各种场景(通过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();

结果

Linqpad results of path checking

答案 2 :(得分:1)

只需为所有远程文件设置规则,它应该(并且必须)在URI中包含协议:

http://
ftp://

对于本地文件,它可以是

file://

表示绝对路径,没有相关协议。

然后简单的正则表达式可以帮助提取正确的信息。

答案 3 :(得分:1)

如果路径格式错误(不存在的路径,空字符串,空字符串)Uri(p).IsFile会抛出异常。 在我看来,最好使用两种方法来辨别什么是:

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

返回: 如果调用者具有所需权限并且path包含现有文件的名称,则为true;否则为false。否则,错误。如果path为null,无效路径或零长度字符串,则此方法也返回false。如果调用者没有足够的权限来读取指定的文件,则不会抛出任何异常,并且无论路径是否存在,该方法都返回false。 //

Microsoft docs: 
public Uri(string uriString);

例外:

T:System.ArgumentNullException:

uriString为空。

T:System.UriFormatException:

uriString为空.-或 - uriString中指定的方案未正确形成。请参见System.Uri.CheckSchemeName(System.String).-或 - uriString包含太多斜杠.-或 - uriString中指定的密码无效.-或 - uriString中指定的主机名无效.-或 - uriString中指定的文件名无效。 - 或 - uriString中指定的用户名无效.-或 - uriString中指定的主机或授权名称不能通过反斜杠终止.-或 - uriString中指定的端口号无效或无法解析.-或 - uriString的长度超过65519个字符.-或 - uriString中指定的方案的长度超过1023个字符.-或 - uriString中的字符序列无效.-或 - uriString中指定的MS-DOS路径必须以c开头:\

答案 4 :(得分:0)

这是@drzaus的避免异常处理方法的版本。有Uri.TryCreate可用。

        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 =>
        {
            if (Uri.TryCreate(test, UriKind.Absolute, out var u))
            {
                return new { test, u.IsAbsoluteUri, u.IsFile };
            }

            return new { test, IsAbsoluteUri = false, IsFile = true };
        }

        ).Dump();

作为扩展方法:

        public static bool IsLocalAbsolutePath(this string input)
        {
            if (Uri.TryCreate(input, UriKind.Absolute, out var uri))
            {
                return uri.IsFile;
            }

            return false;
        }

        public static bool IsRemoteAbsolutePath(this string input)
        {
            if (Uri.TryCreate(input, UriKind.Absolute, out var uri))
            {
                return !uri.IsFile;
            }

            return false;
        }