96 votes

File.Move ne fonctionne pas - le fichier existe déjà

J'ai un dossier :

c : \test

J'essaie ce code :

File.Move(@"c:\test\SomeFile.txt", @"c:\test\Test");

Je reçois l'exception :

Le fichier existe déjà

Le répertoire de sortie existe bel et bien et le fichier d'entrée s'y trouve.

2 votes

Si le fichier d'entrée se trouve déjà dans le répertoire de sortie, alors le fichier existe déjà, ce qui explique l'exception. Vous devez indiquer que vous voulez le fichier original écrasé par le nouveau.

11 votes

On dirait que l'erreur vous dit exactement ce qui ne va pas.

0 votes

@Josh Non. Il semble que Windows ait un comportement de système de fichiers non-POSIX qui rend impossible l'élaboration d'un modèle/routine de mise à jour de fichier transactionnel simple et portable.

161voto

codegecko Points 1380

Ce dont vous avez besoin :

if (!File.Exists(@"c:\test\Test\SomeFile.txt")) {
    File.Move(@"c:\test\SomeFile.txt", @"c:\test\Test\SomeFile.txt");
}

o

if (File.Exists(@"c:\test\Test\SomeFile.txt")) {
    File.Delete(@"c:\test\Test\SomeFile.txt");
}
File.Move(@"c:\test\SomeFile.txt", @"c:\test\Test\SomeFile.txt");

Ce sera soit :

  • Si le fichier n'existe pas à l'emplacement de destination, déplacer le fichier avec succès, ou ;
  • Si le fichier existe à l'emplacement de destination, supprimez-le, puis déplacez le fichier.

Edit : Je devrais clarifier ma réponse, même si elle est la plus votée ! Le second paramètre de File.Move devrait être le paramètre fichier de destination - no un dossier. Vous spécifiez le deuxième paramètre comme étant le dossier de destination, no le nom du fichier de destination - ce qui est ce que File.Move requiert. Donc, votre deuxième paramètre devrait être c:\test\Test\SomeFile.txt .

67voto

Lee Points 463

Vous devez le déplacer vers un autre fichier (plutôt que vers un dossier), ce qui peut également être utilisé pour le renommer.

Bougez :

File.Move(@"c:\test\SomeFile.txt", @"c:\test\Test\SomeFile.txt");

Renommer :

File.Move(@"c:\test\SomeFile.txt", @"c:\test\SomeFile2.txt");

La raison pour laquelle il est dit "Le fichier existe déjà" dans votre exemple, c'est parce que C:\test\Test essaie de créer un fichier Test sans extension, mais ne peut le faire car un dossier existe déjà avec le même nom.

50voto

Mitchell Points 6124

Personnellement, je préfère cette méthode. Cela écrase le fichier sur la destination, supprime le fichier source et empêche également la suppression du fichier source lorsque la copie échoue.

string source = @"c:\test\SomeFile.txt";
string destination = @"c:\test\test\SomeFile.txt";

try
{
    File.Copy(source, destination, true);
    File.Delete(source);
}
catch
{
    //some error handling
}

4 votes

Cela convient pour les petits fichiers (et ne nécessite pas de déplacement atomique), mais pour les gros fichiers, ou les cas où vous devez être sûr de ne pas vous retrouver avec des doublons, c'est problématique.

0 votes

Pourquoi préférez-vous File.Copy , File.Delete sur File.Move ?

10 votes

File.Move n'a pas d'option d'écrasement.

21voto

mheyman Points 795

Vous pouvez faire un P/Invoke pour MoveFileEx() - passer 11 para flags ( MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH )

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
static extern bool MoveFileEx(string existingFileName, string newFileName, int flags);

Ou, vous pouvez simplement appeler

Microsoft.VisualBasic.FileIO.FileSystem.MoveFile(existingFileName, newFileName, true);

après avoir ajouté Microsoft.VisualBasic comme référence.

0 votes

Tout va bien si l'application ne fonctionne que sous Windows. C'est probablement une bonne réponse pour la plupart des gens qui sont prêts à essayer som P/Invoke.

13voto

Todd Points 2386
  1. Avec C# sur .Net Core 3.0 et au-delà, il existe désormais un troisième paramètre booléen :

Dans .NET Core 3.0 et les versions ultérieures, vous pouvez appeler Move(String, String, Boolean) en définissant le paramètre overwrite à true, ce qui remplacera le fichier s'il existe.

Source : Microsoft Docs

  1. Pour toutes les autres versions de .Net, cette réponse est le meilleur. Copiez avec Overwrite, puis supprimez le fichier source. C'est mieux car cela en fait une opération atomique. (J'ai essayé de mettre à jour les MS Docs avec ceci)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X