File utilizzato da un altro processo dopo aver utilizzato File.Create ()


117

Sto cercando di rilevare se un file esiste in fase di esecuzione, in caso contrario, crearlo. Tuttavia ricevo questo errore quando provo a scriverci:

Il processo non può accedere al file "myfile.ext" perché è utilizzato da un altro processo.

string filePath = string.Format(@"{0}\M{1}.dat", ConfigurationManager.AppSettings["DirectoryPath"], costCentre); 
if (!File.Exists(filePath)) 
{ 
    File.Create(filePath); 
} 

using (StreamWriter sw = File.AppendText(filePath)) 
{ 
    //write my text 
}

Qualche idea su come aggiustarlo?

Risposte:


112

Il File.Createmetodo crea il file e apre un FileStreamfile sul file. Quindi il tuo file è già aperto. Non hai davvero bisogno del metodo file.Create:

string filePath = @"c:\somefilename.txt";
using (StreamWriter sw = new StreamWriter(filePath, true))
{
    //write to the file
}

Il valore booleano nel StreamWritercostruttore farà sì che il contenuto venga aggiunto se il file esiste.


Ho provato il codice sopra ma ricevo lo stesso errore quando il file viene creato e quando tenta di scrivere nel file mostra che il file è utilizzato da un altro processo.
Anmol Rathod

@AnmolRathod assicurati di non usare il File.Create()metodo! Lo snippet sopra crea già il file!
Daniel Eisenreich

138
    File.Create(FilePath).Close();
    File.WriteAllText(FileText);

Voglio aggiornare questa risposta per dire che questo non è davvero il modo più efficiente per scrivere tutto il testo. Dovresti usare questo codice solo se hai bisogno di qualcosa di veloce e sporco.

Ero un giovane programmatore quando ho risposto a questa domanda, e allora pensavo di essere una specie di genio per aver trovato questa risposta.


4
Adoro come tutte le altre risposte fossero semplicemente troppo complicate. Le persone non si rendono conto che esiste una risposta più semplice a ogni problema.
Carsen Daniel Yates

14
Lo svantaggio di questo codice è che apre inutilmente il file due volte. Inoltre, non è davvero necessario controllare se il file esiste, poiché il costruttore FileStream lo creerà automaticamente per te se non esiste, a meno che tu non gli dica esplicitamente di non farlo.
reirab

2
@reirab Questo è completamente relativo. Devo controllare se il file esiste e, in caso affermativo, eliminarlo e crearlo di nuovo, quindi questa risposta è preferita nel mio caso.
makoshichi

1
@SO Allora hai un problema diverso dall'OP, solo correlato. Inoltre, nel tuo caso, puoi ancora usare il FileStream(string, FileMode)costruttore e passarlo FileMode.Create , che sovrascriverà qualsiasi file esistente. Non è ancora necessario aprire il file due volte. Inoltre, questa risposta è stata modificata dopo che ho pubblicato il mio commento originale.
reirab

2
Il punto di questa risposta è mostrare che puoi semplicemente aggiungere .Close()alla fine, quindi funziona in ogni caso. Non mi fido del sistema di utilizzo FileStreamper tutto perché non voglio che si verifichi l'eccezione sul fatto FileMode.Createche il file è già lì, specialmente quando voglio cancellare i contenuti e non aggiungerli attraverso FileMode.Open. Per me, FileStreamfunziona davvero solo dopo aver eliminato il file in questione, quindi averci scritto. Dal momento File.Createche lo lascia aperto e bloccato, sembra che aggiungerlo .Close()sia l'unico vero modo per affrontare il mio scenario e i SO.
vapcguy

25

Quando crei un file di testo puoi usare il seguente codice:

System.IO.File.WriteAllText("c:\test.txt", "all of your content here");

Utilizzando il codice del tuo commento. Il file (stream) che hai creato deve essere chiuso. File.Create restituisce il filestream al file appena creato .:

string filePath = "filepath here";
if (!System.IO.File.Exists(filePath))
{
    System.IO.FileStream f = System.IO.File.Create(filePath);
    f.Close();
}
using (System.IO.StreamWriter sw = System.IO.File.AppendText(filePath))
{ 
    //write my text 
}

Non mi sembra di avere un'opzione vicina. Ecco il codice: string filePath = string.Format (@ "{0} \ M {1} .dat", ConfigurationManager.AppSettings ["DirectoryPath"], costCentre); if (! File.Exists (filePath)) {File.Create (filePath); } using (StreamWriter sw = File.AppendText (filePath)) {// scrivi il mio testo}
Brett

File.Createritorna FileStreame che haClose()
Null Head

15
FileStream fs= File.Create(ConfigurationManager.AppSettings["file"]);
fs.Close();

7
Benvenuto in Stackoverflow. Dovresti almeno scrivere una breve descrizione per descrivere la tua risposta / soluzione.
Paresh Mayani

9

File.Create restituisce un FileStream. È necessario chiuderlo dopo aver scritto sul file:

using (FileStream fs = File.Create(path, 1024)) 
        {
            Byte[] info = new UTF8Encoding(true).GetBytes("This is some text in the file.");
            // Add some information to the file.
            fs.Write(info, 0, info.Length);
        }

È possibile utilizzare using per chiudere automaticamente il file.


Sebbene l'OP stia cercando di aprire un StreamWriteras, si può dedurre dal suo uso di File.AppendText.
binki

8

Ho aggiornato la tua domanda con lo snippet di codice. Dopo il corretto rientro, è immediatamente chiaro qual è il problema: usi File.Create()ma non chiudi il fileFileStream che ritorna.

Farlo in questo modo non è necessario, StreamWriterconsente già di aggiungerlo a un file esistente e di creare un nuovo file se non esiste ancora. Come questo:

  string filePath = string.Format(@"{0}\M{1}.dat", ConfigurationManager.AppSettings["DirectoryPath"], costCentre); 
  using (StreamWriter sw = new StreamWriter(filePath, true)) {
    //write my text 
  }

Che usa questo StreamWritercostruttore .


1

Questa domanda è già stata risolta, ma ecco una soluzione del mondo reale che controlla se la directory esiste e aggiunge un numero alla fine se il file di testo esiste. Lo uso per creare file di registro giornalieri su un servizio Windows che ho scritto. Spero che questo aiuti qualcuno.

// How to create a log file with a sortable date and add numbering to it if it already exists.
public void CreateLogFile()
{
    // filePath usually comes from the App.config file. I've written the value explicitly here for demo purposes.
    var filePath = "C:\\Logs";

    // Append a backslash if one is not present at the end of the file path.
    if (!filePath.EndsWith("\\"))
    {
        filePath += "\\";
    }

    // Create the path if it doesn't exist.
    if (!Directory.Exists(filePath))
    {
        Directory.CreateDirectory(filePath);
    }

    // Create the file name with a calendar sortable date on the end.
    var now = DateTime.Now;
    filePath += string.Format("Daily Log [{0}-{1}-{2}].txt", now.Year, now.Month, now.Day);

    // Check if the file that is about to be created already exists. If so, append a number to the end.
    if (File.Exists(filePath))
    {
        var counter = 1;
        filePath = filePath.Replace(".txt", " (" + counter + ").txt");
        while (File.Exists(filePath))
        {
            filePath = filePath.Replace("(" + counter + ").txt", "(" + (counter + 1) + ").txt");
            counter++;
        }
    }

    // Note that after the file is created, the file stream is still open. It needs to be closed
    // once it is created if other methods need to access it.
    using (var file = File.Create(filePath))
    {
        file.Close();
    }
}

1

So che questa è una vecchia domanda, ma voglio solo buttarla là fuori che puoi ancora usare File.Create("filename")", basta aggiungerla .Dispose().

File.Create("filename").Dispose();

In questo modo crea e chiude il file affinché il processo successivo lo utilizzi.


1
File.Create(FilePath).Close();dalla risposta sopra ha this.Dispose(true); GC.SuppressFinalize((object) this);nella sua implementazione.
Ghukas

1

Penso di conoscere il motivo di questa eccezione. Potresti eseguire questo snippet di codice in più thread.


Per me era il problema che scrivevo un file di registro in modo asincrono (in un thread diverso: Task.Run () senza aspettare (apposta), e questo causa l'accesso multithread allo stesso file.
Bence Végert

-1

Prova questo: funziona in ogni caso, se il file non esiste, lo creerà e poi ci scriverà. E se esiste già, nessun problema si aprirà e vi scriverà:

using (FileStream fs= new FileStream(@"File.txt",FileMode.Create,FileAccess.ReadWrite))
{ 
     fs.close();
}
using (StreamWriter sw = new StreamWriter(@"File.txt")) 
 { 
    sw.WriteLine("bla bla bla"); 
    sw.Close(); 
 } 

1
using chiuderà il file chiamando Dispose. Nel tuo file di esempio è stato chiuso due volte
Valentine Zakharenko
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.