文件复制无法创建具有相同名称的文件

时间:2015-10-28 21:13:37

标签: c# .net

我正在将文件从一个位置复制到另一个位置。我遇到了一个问题,有时一个同名的文件会尝试保存,这会破坏程序。所以我添加了下面的逻辑,在复制之前在文件名中添加一个数字:

                int counter = 0;
                try
                {
                    File.Copy(FileToCopy, FileToSave);

                }
                catch (Exception)
                {
                    string CurrentFileName = FileToSave.Split('\\', '\\')[4];
                    string CurretFilePrefix = CurrentFileName.Split('.')[0];
                    string CurrentFileSuffix = CurrentFileName.Split('.')[1];
                    string UpdatedFileName = CurretFilePrefix + "_" + counter + "." + CurrentFileSuffix;
                    File.Copy(FileToCopy, UpdatedFileName);
                    counter++;
                }

但是,这现在导致崩溃,说文件已经存在:

enter image description here

当我检查文件不存在时:

enter image description here

为什么我会收到此异常?如何保存这些文件的副本?

3 个答案:

答案 0 :(得分:2)

解决这个问题的好方法包括(i)循环; (ii)使用Path表达; (iii)当您可以测试文件是否存在时,避免使用try-catch; (iv)对两个线程或进程试图同时执行同一副本并且每个都超过File.Exists检查的极不可能的情况使用特定的异常; (v)避免while-true-forever循环,因为即使最好的代码也可能包含错误,这些错误可能导致服务器上的生产代码中的自旋等待,并且最好有一个异常,告诉你什么时候出了问题。

        int counter = 0;
        string proposedDest = dest;
        while(counter < 5000)
        {
            if (!File.Exists(proposedDest))
            {
                try
                {
                    File.Copy(fileToCopy, proposedDest);
                    break;
                }
                catch (IOException ex) when ((uint)ex.HResult == 0x80070050)
                {
                }
            }
            counter++;
            proposedDest = Path.Combine(Path.GetDirectoryName(dest),
                Path.GetFileNameWithoutExtension(dest) + 
                "_" + counter + Path.GetExtension(dest));
        }
        ;
        if (counter == 5000) 
           throw new Exception($"Could not copy file {fileToCopy} too many retries");

[更好的方法也不会使用通过代码散布的硬编码常量;)]

答案 1 :(得分:1)

由于CurrentFileName是相对的,因此您尝试将文件保存在可执行文件的位置。如果您的文件存在,请检查该目录。

此外,还有更好的方法可以查找文件是否存在,还可以获取给定文件的文件名和扩展名。

即。您应该使用File.Exists方法来确定文件是否存在,而不是使用流控制的异常

if (File.Exists(FileToSave))
{
   FileToSave = GetNewFileName(FileToSave)
}
try
{
  File.Copy(FileToCopy, FileToSave);
}
catch (Exception)
{
  //something went really wrong
}

您还应该使用Path方法获取名称的一部分,而不是“知道”获取文件名的第五部分(Path.GetExtensionPath.GetFileNameWithoutExtension

private string GetNewFileName(string oldFileName){
   var counter = 0;
   var extension = Path.GetExtension(oldFileName);
   var directory = Path.GetDirectoryName(oldFileName);
   var fileName = Path.GetFileNameWithoutExtension(oldFileName);

   var newFileName = Path.Combine(directory, 
      string.Format("{1}_{2}{3}", filename, counter, extension);

   while (File.Exists(newFileName)){
      counter++;
      newFileName = Path.Combine(directory, 
        string.Format("{1}_{2}{3}", filename, counter, extension);
   }

   return newFileName;
}

答案 2 :(得分:0)

改为使用:

string CurrentFileName = System.IO.Path.GetFileName(FileToSave);
string CurretFilePrefix = System.IO.Path.GetFileNameWithoutExtension(FileToSave);
string CurrentFileSuffix = System.IO.Path.GetExtension(FileToSave);
string UpdatedFileName = CurretFilePrefix + "_" + counter + "." + CurrentFileSuffix;

然后你有

File.Copy(FileToCopy, UpdatedFileName);

你确定这不应该

File.Copy(FileToSave, UpdatedFileName); // FileToSave instead of FileToCopy