我开发了一个C#应用程序,它需要通过HTTP,FTP和有时本地文件(文件://)访问许多不同的内容源。
我想通过不同的协议以统一的方式访问这些文件,所以我选择了WebClient来实现这一点。
它适用于MSDN(FTP,HTTP,本地文件等)上记录的所有不同协议,但出现问题...在几次成功请求之后我无法使用URI访问任何文件本地文件(file:// c:\ some_dir \ somefile.ext)。
我已经检查过URI是否正确,如果我在浏览器中输入它,则可以轻松打开文件。我已经认识到一个非常有趣的事情 - 它在本地文件的开头也很好用。如果我尝试使用WebClient加载本地文件的内容,那么一开始就可以正常工作。
我的程序如下:
正如我之前所描述的,如果我在第一步中调用我的WebClient.DownloadData(url)调用,它工作正常,但是当我尝试在第三步的任何线程中访问COMPLETELY相同的URI时,它无法获取URI以“file://”开头的任何本地文件。
我使用非常简单的代码下载/获取本地文件:
WebClient wc = new WebClient();
data = wc.DownloadData(url);
我想知道可能出现什么问题......也许我在前面的步骤中设置了一些内容,或者在并发线程中阻止我访问本地文件?在之前的步骤中,我会从FTP服务器和HTTP上下载内容,这可能导致问题?如果我在主线程的开头尝试,我可以轻松访问任何本地文件。访问FTP内容时,我也设置了凭据。也许这是我后来要求的影响?
答案 0 :(得分:11)
嗯,事实上我在这里,但希望这可以帮助别人。
您最好使用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;
}
答案 1 :(得分: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会出现什么问题......