Using WebClient to access local files

早过忘川 提交于 2019-12-11 04:07:23

问题


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:

  1. Main thread starting
  2. Some initialization on main thread
  3. Multiple threads downloading stuff from different sources
  4. Wait for all threads to finish
  5. 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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!