如何在不覆盖现有文件的情况下复制文件?

时间:2017-05-13 13:26:54

标签: c# .net filesystems

我有以下代码将文件从目录复制到另一个目录,并覆盖文件(如果存在)

string[] dirs = Directory.GetDirectories(path, "*", SearchOption.TopDirectoryOnly);
string[] files = Directory.GetFiles(dirs[0]);

        foreach (string file in files)
        {
            string fname = file.Substring(dirs[0].Length + 1);
            string dist = Path.Combine(dirs[1], fname);
            File.Copy(file, dist, true);
        }

我正在寻找的是将文件复制到目标目录而不覆盖,但保留两个文件。例如,在Windows中,名为" test"的文件的副本很多次都是

test
test - Copy
test - Copy (2)
test - Copy (3)
text
text- Copy
text- Copy (2)
text- Copy (3)

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

更改您的

File.Copy(file, dist, true);

File.Copy(file, dist, false);

如果您查看了MSDN

public static void Copy(string sourceFileName, string destFileName, bool overwrite ) 
  

参数
  sourceFileName类型:System.String要复制的文件   destFileName类型:System.String目标文件的名称   这不能是目录   overwrite类型:System.Boolean如果目标文件可以,则为true   覆盖;否则,错误。

添加异常处理以更改目标文件名并尝试复制直到成功

更新1 您可以尝试使用上面的代码。这似乎比我提供的链接短。我没有针对任何可能的情况对此进行测试,但是对于复制“tmp.txt”这样的简单情况,当存在“tmp - copy.txt”和“tmp - copy(1).txt”时,这是有效的。

更新2对不起,有一个小bug使用。选择而且只有.Count我已修复它

        string sourcePath = @"c:\Users\Admin\Desktop\tmp\test1\";
        string destinationPath = @"c:\Users\Admin\Desktop\tmp\test2\";
        string[] files = Directory.GetFiles(sourcePath);

        foreach (string file in files)
        {
            string fname = file.Substring(sourcePath.Length);
            string dest = Path.Combine(destinationPath, fname);
            if (File.Exists(dest))
            {
                var existingFiles = Directory.GetFiles(destinationPath);
                var fileNum = existingFiles.Count(x => x.Substring(destinationPath.Length).StartsWith(Path.GetFileNameWithoutExtension(fname)));
                dest = Path.Combine(destinationPath, Path.GetFileNameWithoutExtension(dest) + " copy" + (fileNum > 1 ? " (" + (fileNum - 1) + ")" : "") + Path.GetExtension(dest));
                File.Copy(file, dest);
            }
            else
            {
                File.Copy(file, dest);
            }
        }

5次后将同一文件夹复制到同一目标文件夹的结果如下:enter image description here

答案 1 :(得分:1)

        string extention = ".txt";
        string originalFileName = string.Format("test{0}", extention);
        string duplicateFileName = "test";
        string changedName = duplicateFileName;

        int count = 1;
        while (File.Exists(changedName + extention))
        {
            changedName = string.Format("{0} - Copy ({1})",
                duplicateFileName, count++);
        }
        File.Copy(originalFileName, changedName + extention);

答案 2 :(得分:0)

try
{
    if (!string.IsNullOrEmpty(txtsource.Text) &&
        Directory.Exists(txtsource.Text) &&
        !string.IsNullOrEmpty(txtdestination.Text) &&
        Directory.Exists(txtdestination.Text))
    {
        DirectoryInfo dir = new DirectoryInfo(txtsource.Text);
        FileInfo[] files = dir.GetFiles();
        var filtered = files.Where(f => !f.Attributes.HasFlag(FileAttributes.Hidden));
        foreach (var file in filtered)
        {
            try
            {
                string tempPath = Path.Combine(txtdestination.Text, file.Name);
                var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(tempPath);
                var fileExtension = Path.GetExtension(tempPath);
                while (true)
                {
                    if (File.Exists(tempPath))
                    {
                        if (!Path.GetFileNameWithoutExtension(tempPath).EndsWith(" - copy"))
                        {
                            var existingFiles = Directory.GetFiles(txtdestination.Text);
                            tempPath = Path.Combine(txtdestination.Text, fileNameWithoutExtension + " - copy" + fileExtension);
                            continue;
                        }
                        else if (Path.GetFileNameWithoutExtension(tempPath).EndsWith(" - copy") ||
                            Regex.IsMatch(Path.GetFileNameWithoutExtension(tempPath), @" ^.*- copy \(\d+\)"))
                        {
                            var existingFiles = Directory.GetFiles(txtdestination.Text);
                            var fileNum = existingFiles.Count(x => x.Substring(txtdestination.Text.Length).StartsWith(Path.GetFileNameWithoutExtension(tempPath)) &&
                                                                   (Regex.IsMatch(Path.GetFileNameWithoutExtension(tempPath), @" .*- copy$") || Regex.IsMatch(Path.GetFileNameWithoutExtension(tempPath), @" .*- copy \(\d+\)$")));

                            tempPath = Path.Combine(txtdestination.Text, Path.GetFileNameWithoutExtension(tempPath) + (fileNum >= 1 ? " (" + fileNum + ")" : "") + Path.GetExtension(tempPath));
                            continue;
                        }
                    }
                    break;
                }
                file.CopyTo(tempPath, false);
            }
            catch (Exception exception)

            {
                Console.WriteLine(exception);
                throw;
            }
        }
    }
}
catch (Exception exception)
{
    Console.WriteLine(exception);
    throw;
}