2

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

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

它适用于 MSDN 上记录的所有不同协议(FTP、HTTP、本地文件等),但随后出现问题......在几次成功请求后,我无法使用本地文件的 URI 访问任何文件(文件://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 内容时,我还设置了凭据。也许这会影响我以后的请求?

4

2 回答 2

12

好吧,事后我就在这里,但希望这可以帮助某人。

最好使用 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;
}
于 2013-05-09T17:25:53.930 回答
0

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

            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 会出现什么问题......

于 2012-10-25T18:05:54.510 回答