简体   繁体   English

我可以检查一个文件是否存在于一个 URL 中?

[英]can I check if a file exists at a URL?

I know I can locally, on my filesystem, check if a file exists:我知道我可以在本地,在我的文件系统上,检查文件是否存在:

if(File.Exists(path))

Can I check at a particular remote URL?我可以检查特定的远程 URL 吗?

If you're attempting to verify the existence of a web resource, I would recommend using the HttpWebRequest class.如果您尝试验证 Web 资源是否存在,我建议您使用HttpWebRequest类。 This will allow you to send a HEAD request to the URL in question.这将允许您向相关 URL 发送HEAD请求。 Only the response headers will be returned, even if the resource exists.即使资源存在,也只会返回响应头。

var url = "http://www.domain.com/image.png";
HttpWebResponse response = null;
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "HEAD";


try
{
    response = (HttpWebResponse)request.GetResponse();
}
catch (WebException ex)
{
    /* A WebException will be thrown if the status of the response is not `200 OK` */
}
finally
{
    // Don't forget to close your response.
    if (response != null)
    {
        response.Close();
    }
}

Of course, if you want to download the resource if it exists it would most likely be more efficient to send a GET request instead (by not setting the Method property to "HEAD" , or by using the WebClient class).当然,如果您想下载存在的资源,那么发送GET请求很可能会更有效(通过不将Method属性设置为"HEAD" ,或使用WebClient类)。

If you want to just copy & paste Justin 's code and get a method to use, here's how I've implemented it:如果您只想复制并粘贴Justin的代码并获得一种使用方法,那么我是如何实现它的:

using System.Net;

public class MyClass {
    static public bool URLExists (string url) {
        bool result = false;

        WebRequest webRequest = WebRequest.Create(url);
        webRequest.Timeout = 1200; // miliseconds
        webRequest.Method = "HEAD";

        HttpWebResponse response = null;

        try {
            response = (HttpWebResponse)webRequest.GetResponse();
            result = true;
        } catch (WebException webException) {
            Debug.Log(url +" doesn't exist: "+ webException.Message);
        } finally {
            if (response != null) {
                response.Close();
            }
        }

        return result;
    }
}

I'll keep his observation:我会保留他的观察:

If you want to download the resource, and it exists, it would be more efficient to send a GET request instead by not setting the Method property to "HEAD" or by using the WebClient class.如果您想下载资源并且它存在,则通过不将Method属性设置为"HEAD"或使用WebClient类来发送GET请求会更有效。

Below is a simplified version of the code:下面是代码的简化版本:

public bool URLExists(string url)
{
    bool result = true;

    WebRequest webRequest = WebRequest.Create(url);
    webRequest.Timeout = 1200; // miliseconds
    webRequest.Method = "HEAD";

    try
    {
        webRequest.GetResponse();
    }
    catch
    {
        result = false;
    }

    return result;
}

If you are using a unc path or a mapped drive, this will work fine.如果您使用的是 unc 路径或映射驱动器,这将正常工作。

If you are using a web address (http, ftp etc) you are better off using WebClient - you will get a WebException if it doesn't exist.如果您使用的是网址(http、ftp 等),最好使用WebClient - 如果它不存在,您将收到一个 WebException。

public static bool UrlExists(string file)
    {
        bool exists = false;
        HttpWebResponse response = null;
        var request = (HttpWebRequest)WebRequest.Create(file);
        request.Method = "HEAD";
        request.Timeout = 5000; // milliseconds
        request.AllowAutoRedirect = false;

        try
        {
            response = (HttpWebResponse)request.GetResponse();
            exists = response.StatusCode == HttpStatusCode.OK;
        }
        catch
        {
            exists = false;
        }
        finally
        {
            // close your response.
            if (response != null)
                response.Close();
        }
        return exists;
    }

I had the same problem to solve in asp.net core, I've solved with HttpClient我在asp.net core中遇到了同样的问题,我已经用HttpClient解决了

private async Task<bool> isFileExist(string url)
        {
            using (HttpClient client = new HttpClient())
            {
                var restponse = await client.GetAsync(url);

               return restponse.StatusCode == System.Net.HttpStatusCode.OK;
            }
        }

My version:我的版本:

    public bool IsUrlExist(string url, int timeOutMs = 1000)
    {
        WebRequest webRequest = WebRequest.Create(url);
        webRequest.Method = "HEAD";
        webRequest.Timeout = timeOutMs;

        try
        {
            var response = webRequest.GetResponse();
            /* response is `200 OK` */
            response.Close();
        }
        catch
        {
            /* Any other response */
            return false;
        }

        return true;
    }

WebRequest will waiting long time(ignore the timeout user set) because not set proxy, so I change to use RestSharp to do this. WebRequest 会等待很长时间(忽略用户设置的超时时间),因为没有设置代理,所以我改用 RestSharp 来做到这一点。

var client = new RestClient(url);
var request = new RestRequest(Method.HEAD);

 request.Timeout = 5000;
 var response = client.Execute(request);
 result = response.StatusCode == HttpStatusCode.OK;

Thanks for all answers.感谢所有的答案。 And I would like to add my implementation which includes default state when we get errors, for specific cases like mine.我想添加我的实现,其中包括出现错误时的默认状态,适用于像我这样的特定情况。

private bool HTTP_URLExists(String vstrURL, bool vResErrorDefault = false, int vTimeOut = 1200)
{
   bool vResult = false;
   WebRequest webRequest = WebRequest.Create(vstrURL);
   webRequest.Timeout = vTimeOut; // miliseconds
   webRequest.Method = "HEAD";
   HttpWebResponse response = null;
   try
   {
      response = (HttpWebResponse)webRequest.GetResponse();
      if (response.StatusCode == HttpStatusCode.OK) vResult = true;
      else if (response.StatusCode == HttpStatusCode.NotFound) vResult = false;
      else vResult = vResErrorDefault;
   }
       catch (WebException ex)
           {
           
              if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null)
              {
                  var resp01 = (HttpWebResponse)ex.Response;
                  if (resp01.StatusCode == HttpStatusCode.NotFound)
                  {
                      vResult = false;
                  }
                  else
                     {
                         vResult = vResErrorDefault;
                     }
                 }
                 else
                     {
                         vResult = vResErrorDefault;
                     }
                 }
           finally
           {
               // Don't forget to close your response.
               if (response != null)
               {
                   response.Close();
               }
           }
           return vResult;
}

Anoter version with define timeout :另一个版本定义超时:

public bool URLExists(string url,int timeout = 5000)
{
    ...
    webRequest.Timeout = timeout; // miliseconds
    ...
}

This works for me:这对我有用:

bool HaveFile(string url)
        {
            try
            {
                using (WebClient webClient = new WebClient())
                {
                    webClient.DownloadString(url);
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM