Mimica File.Move se la destinazione esiste già

Dalla documentazione di File.Move :

Si noti che se si tenta di sostituire un file spostando un file con lo stesso nome in quella directory, si ottiene una IOException. Non è ansible utilizzare il metodo Move per sovrascrivere un file esistente.

In breve, non è ansible sovrascrivere su Move , quindi per facilitare la sovrascrittura su Move I imitare il comportamento eseguendo un File.Copy seguito da un File.Delete . Qualcosa di simile a:

 if (File.Exists(dstFileName)) { // System.IO.File.Move cannot be used to overwrite existing files, so we're going // to simulate that behavior with a Copy & Delete. File.Copy(procContext.FileName, dstFileName); File.Delete(procContext.FileName); } else File.Move(procContext.FileName, dstFileName); 

La mia domanda è: ci sono situazioni di cui ho bisogno per evitare quale potrebbe portare al file sorgente che viene eliminato senza che sia stato copiato con successo?

La mia comprensione dalla lettura della documentazione è che dal momento che File.Copy non restituisce nulla che dovrebbe generare un’eccezione in ogni caso che non riesce. Qualcuno ha incontrato situazioni in cui questo non è vero?

Ti suggerisco di verificare prima se il file di destinazione esiste e se sì, cancellarlo. Quindi eseguire un’operazione di spostamento normale.

Poiché questa sequenza non è atomica, nel caso in cui la destinazione esista potrebbe essere necessario rinominarla anziché eliminarla, per evitare di perderla nel caso in cui la mossa non vada a buon fine.

Il modo corretto per farlo sarebbe chiamare

 File.Replace(source, destination, copy) 

Questo è il trucco per me

È difficile simulare un’operazione atomica se il sistema operativo non ti dà buone operazioni atomiche. Move è atomico su alcuni ma non su tutti i filesystem, ma non quando si sposta il disco su disco.

Nel caso dello stesso disco, Delete + Move è un po ‘elegante (veloce e sicuro) in quanto non riempie davvero i dati in alcun modo. Potresti estenderlo ulteriormente

 try { Move(dest, tmp); Move(src, dest); Delete(tmp); } catch { try { Move(tmp, dest); } catch { } throw; } 

(Questo rende meno probabile la perdita del file di destinazione quando, per esempio, non hai i diritti necessari per completare la mossa.)

In uno scenario in cui non si sa che si tratta dello stesso disco, la soluzione è abbastanza sicura e abbastanza semplice. Tuttavia, copia i dati anche all’interno dello stesso disco, offrendo una finestra più ampia di rischio di interruzione di corrente.

Questo è sicuro File.Copy avrà esito positivo o sarà generato. Ovviamente, l’eliminazione potrebbe fallire lasciando il file sorgente dietro come garbage.

Se il tuo computer si blocca, tuttavia, non è garantito che l’oepration della copia abbia ancora rafforzato i dati. In questo caso potresti perdere dati.

Durante le normali operazioni questo è sicuro.

Controlla se il file “Target” esiste. Se no, copia il tuo file.

Se sì: Sposta “Target” in dir temp, dove puoi essere sicuro, che la mossa avrà successo. È ansible generare una sottodirectory in Temp con il nome su un UUID. Quindi copia il tuo file.