【问题标题】:Using WebClient to access local files使用 WebClient 访问本地文件
【发布时间】:2012-10-25 18:05:54
【问题描述】:

我开发了一个 C# 应用程序,它需要通过 HTTP、FTP 以及有时还通过本地文件 (file://) 访问许多不同的内容源。

我希望有一个统一的方式来通过不同的协议访问这些文件,所以我选择了 WebClient 来执行此操作。

它适用于 MSDN 上记录的所有不同协议(FTP、HTTP、本地文件等),但随后出现问题......在成功请求几个成功后,我无法使用 URI 访问任何文件本地文件(file://c:\some_dir\somefile.ext)。

我已经检查了 URI 是否正确,如果我在浏览器中输入它,它会轻松打开文件。我已经认识到一件非常有趣的事情 - 它在开始时也适用于本地文件。如果我尝试使用 WebClient 加载本地文件的内容,一开始一切正常。

我的程序如下所示:

  1. 主线程启动
  2. 主线程上的一些初始化
  3. 多个线程从不同来源下载内容
  4. 等待所有线程完成
  5. 单线程处理下载的东西

正如我之前所描述的,如果我将 WebClient.DownloadData(url) 调用放在第一步中,它可以正常工作,但是当我尝试在第三步的任何线程中访问完全相同的 URI 时,它无法获取 URI 以“file://”开头的任何本地文件。

我使用一个非常简单的代码来下载/获取本地文件:

WebClient wc = new WebClient();
data = wc.DownloadData(url);

我想知道会出现什么问题...也许我在前面的步骤中或在并发线程中设置了一些东西,阻止我访问本地文件?在前面的步骤中,我从 FTP 服务器和通过 HTTP 下载内容,也许这会导致问题?如果我在主线程的开头尝试,我可以轻松访问任何本地文件。访问 FTP 内容时,我还设置了凭据。也许这就是影响我以后的请求的原因?

【问题讨论】:

  • 你试过用了吗:file:///c:/tmp/myfile.txt,它有3个“/”
  • 不 - 感谢您的关注!

标签: c# .net uri webclient


【解决方案1】:

好吧,我是事后才来的,但希望这可以帮助某人。

最好使用 Uri 对象,而不是字符串路径。当它是本地文件时,让 Uri 构造函数处理“file://”部分。实际的 URI 更喜欢斜杠而不是反斜杠,即使对于本地文件也是如此。不过,如果您只使用 Uri 对象,则不必担心。

public byte[] Load(string fileName)
{
    Uri uri = new Uri(fileName);
    var client = new WebClient();
    return client.DownloadData(uri);
}

当然,您需要错误处理等,但这基本上对我有用。

如果您只想使用 File.ReadAllBytes() 方法,请按照以下步骤操作。

public byte[] Load(string fileName)
{
    Byte[] retVal = null;
    Uri uri = new Uri(fileName);
    if(uri.Scheme == "file")
    {
        retVal = File.ReadAllBytes(uri.LocalPath);
    }
    else
    {
        var client = new WebClient();
        retVal = client.DownloadData(uri);
    }
    return retVal;
}

【讨论】:

    【解决方案2】:

    现在我有一个非常简单的解决方案来解决这个问题:

                byte[] data;
                if (url.Trim().StartsWith("file://"))
                {                    
                    string fileName = url.Replace("file://","");
                    data = File.ReadAllBytes(fileName);
                }
                else
                {
                    WebClient wc = new WebClient();
                    //wc.Proxy = GlobalProxySelection.GetEmptyWebProxy();
                    data = wc.DownloadData(url);
                }
                // process data...   
    

    这很好用,但我仍然想知道 WebClient 会出现什么问题...

    【讨论】:

    • 这不是通用的。例如。通过这种方式访问​​网络驱动器是行不通的。
    猜你喜欢
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    • 2019-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多