如果文件在归档时已存在,则重命名文件的优雅方式

时间:2011-11-22 11:42:40

标签: c#

我想编写一个归档函数,它将文件夹中的所有文件都移到使用当前日期的归档子文件夹中。该过程可以在一天内运行几次,因此需要处理重复项。

归档规则如下:

  1. 如果文件名已存在,我想添加下划线“_”和 一个数字(从1开始)。
  2. 如果文件名已被修改,我想 增加数字。
  3. 我可以使用大量File.ExistLastIndexOf来拨打电话,但有更优雅的方式吗?也许用LINQ?

    修改

    这是我已经拥有的代码。它有点粗糙,准备好,但它让我知道我想做什么。

    /// <summary>
    /// Move the local file into the archive location.
    /// If the file already exists then add a counter to the file name or increment the existing counter
    /// </summary>
    /// <param name="LocalFilePath">The full path of the file to be archived</param>
    /// <param name="ArchiveFilePath">The proposed full path of the file once it's been archived</param>
    private void ArchiveFile(string LocalFilePath, string ArchiveFilePath)
    {
        // Ensure the file name doesn't already exists in the location we want to move it to
        if (File.Exists(ArchiveFilePath) == true)
        {
            // Does the archive file have a number at the end?
            string[] archiveSplit = Path.GetFileNameWithoutExtension(ArchiveFilePath).Split('_');
            if( archiveSplit.Length == 1)
            {
                // No number detected so append the number 1 to the filename
                string newArcFileName = string.Format("{0}_1.{1}",
                    Path.GetFileNameWithoutExtension(ArchiveFilePath), Path.GetExtension(ArchiveFilePath));
    
                // Create the new full path
                string newArcPath = Path.Combine(Path.GetDirectoryName(ArchiveFilePath), newArcFileName);
    
                // recursively call the archive folder to ensure the new file name doesn't exist before moving
                ArchiveFile( LocalFilePath, newArcPath);
            }
            else
            {
                // Get the number of the last element of the split
                int lastNum = Convert.ToInt32( archiveSplit.Last().Substring(1) ) +1;
    
                // Rebuild the filename using the incremented number
                string newArcFileName = archiveSplit[0];
                for (int i = 1; i < archiveSplit.Length; i++)
                {
                    newArcFileName += archiveSplit[i];
                }
                // finally add the number and extension
                newArcFileName = string.Format("{0}_{1}.{2}", newArcFileName, lastNum, Path.GetExtension(ArchiveFilePath));
    
                // Create the new full path
                string newArcPath = Path.Combine(Path.GetDirectoryName(ArchiveFilePath), newArcFileName);
    
                // recursively call the archive folder to ensure the new file name doesn't exist before moving
                ArchiveFile(LocalFilePath, newArcPath);
            }
        }
        else
        {
            // There is no file with a matching name
            File.Move(LocalFilePath, ArchiveFilePath);
        }
    }
    

3 个答案:

答案 0 :(得分:2)

Directory类有一个接收所有文件列表的方法。该方法允许您指定过滤字符串,如下所示:

Directory.GetFiles(directoryPath, filterString);

如果您已经知道您的文件名前缀,则可以使用该过滤字符串来获取该模式中的所有文件:

filterString = string.Format("{0}_*.{1}", defaultFileNameWithoutExtension, defaultExtension);

然后,您只需选择后缀最高的那个,提取后缀数字,增加后缀并构建新的(未使用的)文件名。

免责声明:这是用心写的,如果有错误可随时编辑:)

答案 1 :(得分:1)

即使您使用LINQ,仍然需要调用

File.Exists,这不会改变。

我建议保持简单 - 使用File.ExistsLastIndexOf进行循环是一个合适的解决方案,除非性能是必要的。

答案 2 :(得分:1)

也许,您应该使用“Path”API并使用EndsWith而不是LastIndexOf :)。

您还可以拥有一个存储文件树的文件。 (注意rsync)

即使它没有改变,你真的想要制作几个相同文件的副本吗?您在寻找更新的“修改日期时间”吗?

http://msdn.microsoft.com/en-us/library/system.io.path.aspx:路径