【问题标题】:c# change file name of relative or absolute uric#更改相对或绝对uri的文件名
【发布时间】:2011-10-06 08:00:50
【问题描述】:

我正在寻找一种干净的方法来更改可能包含多个段的绝对或相对 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);
}

【问题讨论】:

    标签: c# .net url


    【解决方案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)进行测试。

    【讨论】:

    • 我不会提前知道文件名。本质上,我需要在文件名的末尾(扩展名之前)附加一些文本
    • @Ben - 我调整了我的例子。
    • 我已经更新了我的测试以包含一个用于重复目录/文件段的测试。您的代码通过 +1
    【解决方案2】:

    为什么不进行简单的字符串替换?

    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);
        }
    

    【讨论】:

    • @SLaks - 这是一个正则表达式吗?你有 +2,所以我认为它有用吗??
    • @SLaks - 是的,这就是我说在这种情况下会出错的原因。也许 OP 提前知道是否会发生这种情况。
    • @Ben:这是一个示例路径。我指的是 Quimcia 刚才提到的缺点。
    • 啊,好吧,现在说得通了。 @Quimica - 不,我事先不知道。这部分是我最初的解决方案最终如此参与。更改文件名不是问题,它会将其重新附加到原始 url。
    • 顺便说一句,您需要删除“。”从固定。{2} 因为 GetExtension 方法包括“。”
    【解决方案3】:

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

        /// <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 =&gt; s + "_fixed");

    【讨论】:

      【解决方案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);
      }
      

      注意:任何代码都会发布到公共领域。无需署名。

      【讨论】:

        猜你喜欢
        • 2021-06-15
        • 1970-01-01
        • 1970-01-01
        • 2011-07-30
        • 1970-01-01
        • 2010-10-22
        • 1970-01-01
        • 2011-07-14
        • 2022-01-17
        相关资源
        最近更新 更多