c#更改相对或绝对uri的文件名

时间:2011-07-15 16:53:58

标签: c# .net url

我正在寻找一种更改绝对或相对uri文件名的简洁方法,可能包含多个段。我们不知道它是绝对的还是相对的,所以我们需要检测到:

以下是测试用例:

    [Test]
    public void Can_change_path_file_name()
    {
        Fix("file.txt").ShouldEqual("file_fixed.txt");
        Fix("/file.txt").ShouldEqual("/file_fixed.txt");
        Fix("directory/file.txt").ShouldEqual("directory/file_fixed.txt");
        Fix("/directory/file.txt").ShouldEqual("/directory/file_fixed.txt");
        Fix("/directory/subdirectory/file.txt").ShouldEqual("/directory/subdirectory/file_fixed.txt");
        Fix("http://www.test.com/directory/subdirectory/file.txt").ShouldEqual("http://www.test.com/directory/subdirectory/file_fixed.txt");
        Fix("/directory/file/file.txt").ShouldEqual("/directory/file/file_fixed.txt");
    }

    private string Fix(string uri)
    {
       // fill me with goodness
    }

我的解决方案有效,但似乎有点牵扯。我已经在下面发布了以防你想要更好的方法:

private string Fix(string uri)
{
    var fileName = Path.GetFileNameWithoutExtension(uri);
    var extension = Path.GetExtension(uri);
    fileName += "_fixed" + extension;

    var path = uri.Contains('/') ? uri.Substring(0, uri.LastIndexOf('/') + 1) : "";
    return Combine(path, fileName);
}

private string Combine(string path1, string path2)
{
    if (path1 == null)
    {
        throw new ArgumentNullException("path1");
    }

    if (path2 == null)
    {
        throw new ArgumentNullException("path2");
    }

    if (String.IsNullOrEmpty(path2))
    {
        return path1;
    }

    if (String.IsNullOrEmpty(path1))
    {
        return path2;
    }

    if (path2.StartsWith("http://") || path2.StartsWith("https://"))
    {
        return path2;
    }

    var ch = path1[path1.Length - 1];

    if (ch != '/')
    {
        return (path1.TrimEnd('/') + '/' + path2.TrimStart('/'));
    }

    return (path1 + path2);
}

4 个答案:

答案 0 :(得分:4)

没有正则表达式,没有字符串索引。

只需使用.NET Path方法来检索和重新组合新文件名:

/// <summary>
/// Partner to Path.ChangeExtension. This function changes the base filename portion
/// </summary>
/// <param name="path"></param>
/// <param name="newFilename"></param>
/// <returns></returns>
public static String ChangeFilename(String path, String newFilename)
{
   String directoryName = Path.GetDirectoryName(path); //e.g. "C:\Temp\foo.dat" ==> "C:\Temp"
   //String oldFilename = Path.GetFileName(path); //e.g. "C:\Temp\foo.dat" ==> "foo.dat"
   //String filenameWithoutExtension = Path.GetFileNameWithoutExtension(path); //e.g. "C:\Temp\foo.dat" ==> "foo"
   String extension = Path.GetExtension(path); //e.g. "C:\Temp\foo.dat" ==> ".dat"

   //Reassemble as
   //    directoryName \ newFilename dotExtension
   return String.Format("{0}{1}{2}{3}",
         directoryName, 
         Path.DirectorySeparatorChar,
         newFilename,
         extension);
}
  

注意:任何代码都会发布到公共域中。无需归属。

答案 1 :(得分:3)

为什么不换一个简单的字符串?

private string Fix(string uri)
{
    var fileName = Path.GetFileNameWithoutExtension(uri);
    var extension = Path.GetExtension(uri);

    return uri.Replace(string.Format("{0}{1}", fileName, extension), string.Format("{0}_fixed{1}", fileName, extension));
}

如果您的文件名也会出现在uri的其他部分中,那么这只会出错。

另一个没有这个缺点的选择是:

private string Fix(string uri)
    {
        var fileName = Path.GetFileNameWithoutExtension(uri);
        var extension = Path.GetExtension(uri);
        var slashIndex = uri.LastIndexOf("/");

        return string.Format("{0}{1}_fixed{2}", uri.Substring(0, slashIndex + 1), fileName, extension);
    }

答案 2 :(得分:1)

这样的正则表达怎么样?
\b[a-zA-Z0-9]+\.[a-zA-Z0-9]+$

这应该找到file的所有结尾,然后是扩展名。

接下来,如果您捕获file ...

\b([a-zA-Z0-9]+)(\.[a-zA-Z0-9]+)$

...然后你可以replace

var result = Regex.Replace( 
    input,
    @"\b([a-zA-Z0-9]+)(\.[a-zA-Z0-9]+)$",
    "$1_fixed$2" );

你已经完成了。在编码之前,您可以使用在线正则表达式测试器(如this one进行测试。

答案 3 :(得分:1)

我已将工作解决方案包装成实用程序方法。应该对别人有所帮助。

    /// <summary>
    /// Changes the file name of the <paramref name="uri"/> using the given <paramref name="modifier"/>
    /// </summary>
    /// <param name="uri">A relative or absolute uri</param>
    /// <param name="modifier">A function to apply to the filename</param>
    /// <returns>The modified uri</returns>
    public static string ModifyUriFileName(string uri, Func<string, string> modifier)
    {
        if (string.IsNullOrEmpty(uri))
        {
            throw new ArgumentNullException("uri");
        }

        var fileName = Path.GetFileNameWithoutExtension(uri);
        var extension = Path.GetExtension(uri);
        var path = uri.Substring(0, uri.LastIndexOf('/') + 1);

        return string.Format("{0}{1}{2}", path, modifier(fileName), extension);
    }

用法:

return CommonUtils.ModifyUriFileName(uri, s => s + "_fixed");

相关问题