现在,我一直在寻找适用于URL的Path.Combine方法。这与Path.Combine for URLs?类似,但有一个很大的区别。
我将举例说明。假设我们有一个基本网址:http://example.com/somefolder
和一个文件:foo.txt
。因此,完整路径将是:http://example.com/somefolder/foo.txt
。听起来很简单吧?哈
我尝试了Uri课程:Uri.TryCreate(new Uri("http://example.com/somefolder"), "foo.txt", out x);
,结果是"http://example.com/foo.txt"
。
然后我尝试了路径:System.IO.Path.Combine("http://example.com/somefolder", "foo.txt");
导致"http://example.com/somefolder\foo.txt"
...更接近,但仍然没有。
对于踢,然后我尝试了System.IO.Path.Combine("http://example.com/somefolder/", "foo.txt")
,结果是"http://example.com/somefolder/foo.txt"
。
最后一个工作,但它基本上是在那时进行字符串连接。
所以我认为我有两个选择:
我是否错过了内置的框架方法?
更新:我的用例是下载一堆文件。我的代码如下所示:
public void Download()
{
var folder = "http://example.com/somefolder";
var filenames = getFileNames(folder);
foreach (var name in filenames)
{
downloadFile(new Uri(folder + "/" + name));
}
}
我不得不在Uri构造函数中使用字符串连接,并且必须检查是否需要斜杠(我在代码中省略了它)。
在我看来,我想要做的事情会出现很多,因为除了http之外,Uri类还会处理很多其他协议。
答案 0 :(得分:17)
Flurl [披露:我是作者]是一个很小的网址构建器库,可以用Url.Combine
方法填补空白:
string url = Url.Combine("http://www.foo.com/", "/too/", "/many/", "/slashes/", "too", "few");
// result: "http://www.foo.com/too/many/slashes/too/few"
你可以通过NuGet获得它:Install-Package Flurl
。
我还想指出,您可以通过并行下载文件来显着提高代码的效率。有几种方法可以做到这一点。如果您使用的是.NET 4.5或更高版本,并且可以将downloadFile
重写为异步方法,那么您最好的选择是将for
循环替换为以下内容:
var tasks = filenames.Select(f => downloadFileAsync(Url.Combine(folder, f)));
await Task.WhenAll(tasks);
否则,如果你坚持使用.NET 4,你仍然可以使用Parallel.ForEach轻松实现并行性:
Parallel.ForEach(filenames, f => downloadFile(Url.Combine(folder, f)));
答案 1 :(得分:7)
这就是Uri课程的运作方式。
var otherUri = new Uri("http://example.com/somefolder"));
// somefolder is just a path
var somefolder = otherUri.GetComponents(UriComponents.PathAndQuery, UriFormat.UriEscaped);
// example one
var baseUri = new Uri("http://example.com/");
var relativeUri = new Uri("somefolder/file.txt",UriKind.Relative);
var fullUri = new Uri(baseUri, relativeUri);
// example two
var baseUri = new Uri("http://example.com/somefolder");
var relativeUri = new Uri("somefolder/file.txt",UriKind.Relative);
var fullUri = new Uri(baseUri, relativeUri);
// example three
var baseUri = new Uri("http://example.com/");
var fullUri = new Uri(baseUri, "somefolder/file.txt");
基本上通过字符串操作最简单,然后执行
var isValid = Uri.TryCreate(..., out myUri);
如果您想了解更多信息。 看看这篇文章C# Url Builder Class
更新回答
当提到基础uri时,它总是http://example.com/右边的任何东西都只是路径。
void Main()
{
var ub = new UriBuilder("http://example.com/somefolder");
ub.AddPath("file.txt");
var fullUri = ub.Uri;
}
public static class MyExtensions
{
public static UriBuilder AddPath(this UriBuilder builder, string pathValue)
{
var path = builder.Path;
if (path.EndsWith("/") == false)
{
path = path + "/";
}
path += Uri.EscapeDataString(pathValue);
builder.Path = path;
}
}
答案 2 :(得分:1)
我有一个静态方法用于此目的:
// Combines urls like System.IO.Path.Combine
// Usage: this.Literal1.Text = CommonCode.UrlCombine("http://stackoverflow.com/", "/questions ", " 372865", "path-combine-for-urls");
public static string UrlCombine(params string[] urls) {
string retVal = string.Empty;
foreach (string url in urls)
{
var path = url.Trim().TrimEnd('/').TrimStart('/').Trim();
retVal = string.IsNullOrWhiteSpace(retVal) ? path : new System.Uri(new System.Uri(retVal + "/"), path).ToString();
}
return retVal;
}
答案 3 :(得分:1)
这是一个接近上述答案的LINQ版本。
public static string UrlCombine( this string root, params string[] parts)
{
return parts
.Select(part => part.Trim().TrimEnd('/').TrimStart('/').Trim())
.Aggregate(root, (current, path) => current + ("/" + path));
}
var x = "http://domain.com";
var p = "path";
var u = x.UrlCombine(p, "test.html"); // http://domain.com/path/test.html
答案 4 :(得分:0)
df.columns = pd.MultiIndex.from_arrays([df.columns,
['LR'] * len(df.columns)],
names=('SIMULATION','IDX'))
print (df)
SIMULATION Sim_1 Sim_2 Sim_3
IDX LR LR LR
2016 1.063708 1.008885 1.028539
2017 1.114644 0.994331 1.043218
使用示例:
private string CombineUrl(params string[] urls)
{
string result = "";
foreach (var url in urls)
{
if (result.Length > 0 && url.Length > 0)
result += '/';
result += url.Trim('/');
}
return result;
}
结果网址是" http://something.com/task/status/dfgd/111/qqq"