Datei, die von einem anderen Prozess nach Verwendung von File.Create () verwendet wird

117

Ich versuche festzustellen, ob eine Datei zur Laufzeit vorhanden ist. Wenn nicht, erstellen Sie sie. Ich erhalte jedoch diesen Fehler, wenn ich versuche, darauf zu schreiben:

Der Prozess kann nicht auf die Datei 'myfile.ext' zugreifen, da sie von einem anderen Prozess verwendet wird.

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 
}

Irgendwelche Ideen, wie man das Problem beheben kann?

Brett
quelle

Antworten:

112

Die File.CreateMethode erstellt die Datei und öffnet eine FileStreamDatei. Ihre Datei ist also bereits geöffnet. Sie brauchen die file.Create-Methode überhaupt nicht:

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

Der Boolesche Wert im StreamWriterKonstruktor bewirkt, dass der Inhalt angehängt wird, wenn die Datei vorhanden ist.

Chris Dunaway
quelle
Ich habe den obigen Code ausprobiert, aber es wird der gleiche Fehler angezeigt, wenn die Datei erstellt wird und wenn versucht wird, in die Datei zu schreiben, wird angezeigt, dass die Datei von einem anderen Prozess verwendet wird.
Anmol Rathod
@AnmolRathod gehen Sie sicher, dass Sie keine File.Create()Methode verwenden! Das obige Snippet erstellt die Datei bereits!
Daniel Eisenreich
138
    File.Create(FilePath).Close();
    File.WriteAllText(FileText);

Ich möchte diese Antwort aktualisieren, um zu sagen, dass dies nicht wirklich die effizienteste Art ist, den gesamten Text zu schreiben. Sie sollten diesen Code nur verwenden, wenn Sie etwas schnelles und schmutziges benötigen.

Ich war ein junger Programmierer, als ich diese Frage beantwortete, und damals dachte ich, ich wäre eine Art Genie, um diese Antwort zu finden.

Carsen Daniel Yates
quelle
4
Ich finde es toll, dass all die anderen Antworten einfach zu kompliziert waren. Die Leute wissen nicht, dass es für jedes Problem eine einfachere Antwort gibt.
Carsen Daniel Yates
14
Der Nachteil dieses Codes ist, dass er die Datei unnötigerweise zweimal öffnet. Außerdem muss nicht unbedingt überprüft werden, ob die Datei überhaupt vorhanden ist, da der FileStream-Konstruktor sie automatisch für Sie erstellt, wenn sie nicht vorhanden ist, es sei denn, Sie weisen ihn ausdrücklich an, dies nicht zu tun.
Reirab
2
@reirab Dies ist völlig relativ. Ich muss überprüfen, ob die Datei vorhanden ist, und wenn ja, löschen Sie sie und erstellen Sie sie erneut. Daher wird diese Antwort in meinem Fall bevorzugt.
Makoshichi
1
@SO Dann hast du ein anderes Problem als das OP, nur ein verwandtes. In Ihrem Fall können Sie den FileStream(string, FileMode)Konstruktor auch weiterhin verwenden und FileMode.Create übergeben , wodurch alle vorhandenen Dateien überschrieben werden. Es ist immer noch nicht erforderlich, die Datei zweimal zu öffnen. Diese Antwort wurde auch bearbeitet, nachdem ich meinen ursprünglichen Kommentar gepostet habe.
Reirab
2
Der Sinn dieser Antwort ist zu zeigen, dass Sie nur .Close()am Ende hinzufügen können , damit es auf jeden Fall funktioniert. Ich misstraue dem System der Verwendung FileStreamfür alles, weil ich nicht möchte, dass die Ausnahme auftritt, FileMode.Createdass die Datei bereits vorhanden ist - insbesondere, wenn ich den Inhalt löschen und nicht durchhängen möchte FileMode.Open. Funktioniert für mich FileStreamerst dann wirklich, wenn Sie die betreffende Datei entfernt und dann darauf geschrieben haben. Da File.Createes offen und gesperrt bleibt, scheint .Close()es der einzige wirkliche Weg zu sein, mit meinem Szenario und meinen SOs umzugehen.
Vapcguy
25

Beim Erstellen einer Textdatei können Sie den folgenden Code verwenden:

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

Verwenden Sie den Code aus Ihrem Kommentar. Die von Ihnen erstellte Datei (Stream) muss geschlossen sein. File.Create gibt den Dateistream an die gerade erstellte Datei zurück:

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 
}
Ralf de Kleine
quelle
Ich scheine keine enge Option zu haben. Hier ist der Code: 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)) {// schreibe meinen Text}
Brett
File.Createkehrt zurück FileStreamund das hatClose()
Null Head
15
FileStream fs= File.Create(ConfigurationManager.AppSettings["file"]);
fs.Close();
user3430377
quelle
7
Willkommen bei Stackoverflow. Sie sollten mindestens eine kurze Beschreibung schreiben, um Ihre Antwort / Lösung zu beschreiben.
Paresh Mayani
9

File.Create gibt einen FileStream zurück. Sie müssen das schließen, wenn Sie in die Datei geschrieben haben:

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);
        }

Sie können using verwenden, um die Datei automatisch zu schließen.

kimtiede
quelle
Obwohl das OP versucht, ein zu öffnen, StreamWriterwie aus seiner Verwendung von abgeleitet werden kann File.AppendText.
Binki
8

Ich habe Ihre Frage mit dem Code-Snippet aktualisiert. Nach dem richtigen Einrücken ist sofort klar, wo das Problem liegt: Sie verwenden das zurückgegebene, File.Create()aber schließen es nicht FileStream.

Dies ist nicht erforderlich. Sie können StreamWriterbereits an eine vorhandene Datei anhängen und eine neue Datei erstellen, falls diese noch nicht vorhanden ist. So was:

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

Welches verwendet diesen StreamWriterKonstruktor .

Hans Passant
quelle
1

Diese Frage wurde bereits beantwortet, aber hier ist eine reale Lösung, die prüft, ob das Verzeichnis vorhanden ist, und am Ende eine Nummer hinzufügt, wenn die Textdatei vorhanden ist. Ich verwende dies zum Erstellen von täglichen Protokolldateien in einem von mir geschriebenen Windows-Dienst. Ich hoffe das hilft jemandem.

// 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();
    }
}
Halcyon
quelle
1

Ich weiß, dass dies eine alte Frage ist, aber ich möchte sie nur da rauswerfen, die Sie noch verwenden File.Create("filename")"können. Fügen Sie .Dispose()sie einfach hinzu .

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

Auf diese Weise wird die Datei erstellt und geschlossen, damit der nächste Prozess sie verwenden kann.

Ich bin Batman
quelle
1
File.Create(FilePath).Close();aus der obigen Antwort hat this.Dispose(true); GC.SuppressFinalize((object) this);in seiner Umsetzung.
Ghukas
1

Ich glaube, ich kenne den Grund für diese Ausnahme. Möglicherweise führen Sie dieses Code-Snippet in mehreren Threads aus.

Kusala Subasinghe
quelle
Für mich war das Problem, dass ich eine Protokolldatei auf asynchronem Weg schreibe (in einem anderen Thread: Task.Run (), ohne zu warten (absichtlich), und dies verursacht Multithread-Zugriff auf dieselbe Datei.
Bence Végert
-1

Versuchen Sie Folgendes: Es funktioniert auf jeden Fall. Wenn die Datei nicht vorhanden ist, wird sie erstellt und anschließend geschrieben. Und wenn es bereits existiert, wird es problemlos geöffnet und darauf geschrieben:

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(); 
 } 
PureSilence
quelle
1
using schließt die Datei per Aufruf Dispose. In Ihrer Beispieldatei wurde zweimal geschlossen
Valentine Zakharenko