问题
I develop a C# application that needs to access many different content source both through HTTP, FTP and sometimes local files also (file://).
I wanted to have a uniform way that I access these files through different protocols, so I had choosen WebClient to do this.
It works well for all the different protocols as documented on MSDN (FTP, HTTP, local files, and so on), but then something goes wrong... after a couple successfull requests I just cannot access any files using URI for local files (file://c:\some_dir\somefile.ext).
I have already checked the URI is correct, If I enter it in a browser it opens the file easily. I have recognized one really interesting thing - It also works well in the beginning for local files. If I try to load contents of a local file using WebClient, right at the start it all works well.
My program looks like this:
- Main thread starting
- Some initialization on main thread
- Multiple threads downloading stuff from different sources
- Wait for all threads to finish
- Single thread processing dowloaded stuff
As I've described before if I put my WebClient.DownloadData(url) invocation in the first step, it works fine, but when I try to access the COMPLETELY same URI in any of the threads of the third step, it fails to get any local files with URI starting with "file://".
I use a very simple code to download/get local files:
WebClient wc = new WebClient();
data = wc.DownloadData(url);
I wonder what could go wrong... Maybe I set something in the previous steps or in a concurrent thread that prevents me to access local files? In previous steps I do dowload content from FTP servers and through HTTP, maybe that causes the problem? I can easily access any local file if I try at the beginning of the main thread. When accessing FTP content I set credentials also. Maybe this is what effects my later requests?
回答1:
Well, I'm here way after the fact, but hopefully, this can help someone.
Rather than string paths, you're better using Uri objects. When it's a local file, let the Uri constructor take care of the "file://" part. The actual URI prefers slashes to backslashes, even for local files. If you just use the Uri object, you don't have to worry about that, though.
public byte[] Load(string fileName)
{
Uri uri = new Uri(fileName);
var client = new WebClient();
return client.DownloadData(uri);
}
Of course, you need error-handling and such, but this is basically what works for me.
If you want to just use the File.ReadAllBytes() method, here's how you would do it.
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:
Now I have a very simple solution to solve this:
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...
This works well, but I still wonder what could go wrong with the WebClient...
来源:https://stackoverflow.com/questions/13074555/using-webclient-to-access-local-files