CodeGym /Corsi /C# SELF /Spostamento di file e directory

Spostamento di file e directory

C# SELF
Livello 40 , Lezione 3
Disponibile

1. Introduzione

Gli scenari in cui servono operazioni di spostamento sono tantissimi: spostare i file "scaricati" dalla cartella temporanea alla cartella Documenti, organizzare in massa le foto, rinominare con uno schema, processare posta e log. Il file system ama l'ordine — o almeno una sua apparenza! E un buon sviluppatore deve saper mettere ordine.

Inoltre questi task spesso vengono proposti ai colloqui: "Scrivi una utility che rinomini tutti i file aggiungendo un numero di versione", o "Crea un comando che sposti i documenti obsoleti in un archivio". Vediamo come farlo in C#.

Panoramica delle possibilità

In .NET ci sono due modi principali per spostare e rinominare: usare i metodi statici (File.Move, Directory.Move) oppure i metodi di istanza (FileInfo.MoveTo, DirectoryInfo.MoveTo). Tutti questi metodi sotto il cofano fanno quasi la stessa cosa — cambia soprattutto la sintassi.

Come .NET "vede" lo spostamento e il rinominare?

Attenzione! Rinomare e spostare sono essenzialmente la stessa operazione: un file o una cartella sono identificati dal loro percorso. Se il percorso cambia — si considera che l'oggetto sia "spostato" o "rinominato". Se cambi solo il nome ma lasci la stessa directory — è un rinomina. Se cambi tutto il percorso — è uno spostamento. Filosofia da gatto di Schrödinger: l'oggetto è sia spostato sia rinominato se indichi un nuovo percorso con un nuovo nome!

2. Spostare e rinominare file: esempi

Andremo dal semplice al complesso e continueremo con il nostro mini-file manager.

Metodo statico File.Move

Ecco un esempio di come spostare (o rinominare) un file:


// Spostiamo il file test1.txt in un'altra cartella con un nuovo nome
File.Move(@"C:\Temp\test1.txt", @"C:\Archive\test1_archived.txt");

E se vuoi solo rinominare il file nella stessa cartella:


// Semplicemente cambiamo il nome del file
File.Move(@"C:\Temp\test1.txt", @"C:\Temp\test_renamed.txt");

Ecco tutta la magia! .NET semplicemente "rimuove" un percorso e "assegna" all'oggetto un altro percorso, se entrambi i percorsi sono accessibili e non ci sono conflitti.

Metodo statico Directory.Move

Con le cartelle — analogamente:


// Spostiamo la cartella
Directory.Move(@"C:\Temp\OldFolder", @"C:\Temp\NewFolder");

Puoi sia rinominare la cartella (nuovo nome nella stessa directory), sia spostarla interamente in un altro posto.

3. Metodi di istanza: FileInfo.MoveTo e DirectoryInfo.MoveTo

Quando hai già un oggetto FileInfo o DirectoryInfo, puoi chiamare il metodo MoveTo():


var fileInfo = new FileInfo(@"C:\Temp\test1.txt");
fileInfo.MoveTo(@"C:\Archive\test1_archived.txt");

// Cartelle:
var dirInfo = new DirectoryInfo(@"C:\Temp\OldFolder");
dirInfo.MoveTo(@"C:\Temp\NewFolder");

Anche qui: se il nuovo percorso è la stessa directory ma con un nome diverso, succede un rinomina; se è un'altra directory — uno spostamento.

4. E se il file esiste già nella destinazione?

Qui iniziano le sottigliezze che amano "mordere" nel momento meno opportuno.

File.Move

Se nel percorso di destinazione esiste già un file — verrà lanciata un'eccezione IOException, e il tuo codice "cade":


try
{
    File.Move("data.txt", "archive\\data.txt");
}
catch (IOException ex)
{
    Console.WriteLine("Il file di destinazione esiste già! " + ex.Message);
}

FileInfo.MoveTo

Stessa storia — IOException se il file di destinazione esiste già.

Directory.Move

Con le cartelle la situazione è ancora più severa: se la cartella di destinazione esiste già — eccezione. Non puoi spostare una cartella in una cartella già occupata.

Mora: Controlla sempre che non esista già quel file o quella cartella dove stai per scrivere!


// Controlliamo con calma se esiste un file al percorso di destinazione
if (!File.Exists("archive\\data.txt"))
{
    File.Move("data.txt", "archive\\data.txt");
}
else
{
    Console.WriteLine("Il file di destinazione esiste già!");
}

5. Sottigliezze utili

Esempio di rinomina di una cartella


var oldDir = @"C:\Projects\OldReport";
var newDir = @"C:\Projects\NewReport";

// Controlliamo che la nuova cartella non esista e che la vecchia esista
if (Directory.Exists(oldDir) && !Directory.Exists(newDir))
{
    Directory.Move(oldDir, newDir);
    Console.WriteLine("Cartella rinominata con successo.");
}
else
{
    Console.WriteLine("Errore: cartella sorgente non trovata o la nuova esiste già.");
}

Rinomina tenendo conto del contenuto annidato

Tutto il contenuto della cartella (sottocartelle, file) verrà spostato insieme senza comandi aggiuntivi! Comodo: con un solo comando una cartella con qualsiasi annidamento finisce nel nuovo posto.

Best practice e metodi utili della classe Path

Quando rinomini o sposti file, usa i metodi della classe System.IO.Path per costruire correttamente il nuovo percorso o modificare il nome del file:

  • Ottenere il nome file senza estensione: Path.GetFileNameWithoutExtension(path)
  • Sostituire solo l'estensione: Path.ChangeExtension(path, ".bak")
  • Costruire un nuovo percorso con un altro nome: Path.Combine(Path.GetDirectoryName(path), "newname.txt")

string oldPath = @"C:\Reports\2023_Final.docx";
string newName = "2023_Archive.docx";
string newPath = Path.Combine(Path.GetDirectoryName(oldPath)!, newName);

File.Move(oldPath, newPath);

6. Note importanti ed errori tipici

Permessi e lock

Se non hai permessi di scrittura su uno dei percorsi — verrà lanciata un'eccezione UnauthorizedAccessException. Analogamente, se il file è usato da un altro processo (ad esempio aperto in Word), otterrai un errore. È un caso molto comune.

Spostamento tra dischi e volumi diversi

Praticamente, File.Move esegue un'operazione veloce di rinomina all'interno dello stesso volume/disco. Se provi a spostare un file da C a D — .NET eseguirà automaticamente una copia seguita dall'eliminazione del file originale. Se qualcosa va storto (ad esempio il disco di destinazione è pieno), il file sorgente resterà al suo posto.

Curiosità: quasi tutti i file system moderni supportano la "rinomina/spostamento veloce" all'interno del volume, mentre tra volumi diversi avviene copia + cancellazione.

Spostare intere cartelle (Directory.Move)

Non puoi spostare una cartella dentro se stessa o in una sua sottocartella (ad esempio C:\Data in C:\Data\Archive) — questo causerà un errore.

Come spostare in modo sicuro?

Prima di ogni spostamento, specialmente massivo, verifica l'esistenza della sorgente (File.Exists, Directory.Exists) e l'assenza di conflitti nella destinazione. E non dimenticare il try-catch: il file system è una signora capricciosa, può lanciare un errore nel momento più inaspettato.

Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION