Path.Combine for URLs (part 2)

c#, path, uri

Solution

Flurl [disclosure: I'm the author] is a tiny URL builder library that can fill the gap with its `Url.Combine` method:

string url = Url.Combine("http://www.foo.com/", "/too/", "/many/", "/slashes/", "too", "few");
// result: "http://www.foo.com/too/many/slashes/too/few"

You can get it via NuGet: `Install-Package Flurl`.

I also wanted to point out that you can dramatically improve the efficiency of your code by downloading the files in parallel. There's a couple ways to do that. If you're on .NET 4.5 or above and can rewrite `downloadFile` as an async method, then your best option would be to replace your `for` loop with something like this:

var tasks = filenames.Select(f => downloadFileAsync(Url.Combine(folder, f)));
await Task.WhenAll(tasks);

Otherwise, if you're stuck on .NET 4, you can still achieve parallelism easily by using Parallel.ForEach:

Parallel.ForEach(filenames, f => downloadFile(Url.Combine(folder, f)));

Problem

For awhile now, I've been searching for a Path.Combine method that works on URLs. This is similiar to Path.Combine for URLs? with one big difference. I'll illustrate with an example. Say we have a base url: `http://example.com/somefolder` and a file: `foo.txt`. Thus, the full path would be: `http://example.com/somefolder/foo.txt`. Sounds simple, right? Ha. I tried the Uri class: `Uri.TryCreate(new Uri("http://example.com/somefolder"), "foo.txt", out x);` which resulted in `"http://example.com/foo.txt"`. Then I tried Path: `System.IO.Path.Combine("http://example.com/somefolder", "foo.txt");` which resulted in `"http://example.com/somefolder\foo.txt"`... Closer, but still no. For kicks, I then tried: `System.IO.Path.Combine("http://example.com/somefolder/", "foo.txt")` which resulted in `"http://example.com/somefolder/foo.txt"`. The last one worked, but it's basically doing string concatenation at that point. So I think I have two options: - Use Path.Combine and replace all \ with / - Use basic string concatenation Am I missing a built in framework method for this? UPDATE: The usage case I have is for downloading a bunch of files. My code looks like this: ``` public void Download() { var folder = "http://example.com/somefolder"; var filenames = getFileNames(folder); foreach (var name in filenames) { downloadFile(new Uri(folder + "/" + name)); } } ``` I'm miffed at having to use string concat in the Uri constructor, as well having to check if the slash is needed (which I omitted in the code). It seems to me that what I'm trying to do would come up a lot, since the Uri class handles a lot of other protocols besides http.

Original source

Related problems