File.Create()を使用した後に別のプロセスによって使用されているファイル


117

実行時にファイルが存在するかどうかを検出しようとしています。存在しない場合は作成します。しかし、書き込もうとするとこのエラーが発生します。

別のプロセスによって使用されているため、プロセスはファイル 'myfile.ext'にアクセスできません。

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 
}

それを修正する方法についてのアイデアはありますか?

回答:


112

このFile.Createメソッドはファイルを作成し、ファイルを開きFileStreamます。したがって、ファイルはすでに開いています。file.Createメソッドは本当に必要ありません。

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

StreamWriterコンストラクタのブール値により、ファイルが存在する場合はコンテンツが追加されます。


上記のコードを試しましたが、ファイルが作成され、ファイルに書き込もうとしたときに同じエラーが発生し、ファイルが他のプロセスで使用されていることを示しています。
Anmol Rathod

@AnmolRathodはFile.Create()メソッドを使用しないことを確認してください!上記のスニペットはすでにファイルを作成しています!
ダニエルアイゼンライヒ

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

これは、すべてのテキストを記述する最も効率的な方法ではないことを伝えるために、この回答を更新したいと思います。このコードは、素早く簡単なものが必要な場合にのみ使用してください。

私がこの質問に答えたとき、私は若いプログラマーでした。当時、私はこの答えを思いついたのは、ある種の天才だと思いました。


4
他のすべての答えがあまりにも複雑すぎるのが好きです。人々はすべての問題に対してより簡単な答えがあることを理解していません。
Carsen Daniel Yates

14
このコードの欠点は、ファイルを不必要に2回開くことです。また、ファイルが存在しない場合はFileStreamコンストラクターが自動的に作成するため、ファイルが存在するかどうかを確認する必要はありません。
reirab 2013

2
@reirabこれは完全に相対的です。ファイルが存在するかどうかを確認する必要があります。存在する場合は、削除して再度作成する必要があるため、私の場合はこの回答をお勧めします。
makoshichi 2016

1
@SO次に、OPとは別の問題が発生します。関連する問題です。また、あなたのケースでは、FileStream(string, FileMode)コンストラクタを使用してFileMode.Createを渡すだけで、既存のファイルを上書きできます。それでもファイルを2回開く必要はありません。また、この回答は、元のコメントを投稿した後に編集されました。
reirab

2
この答えのポイントは.Close()、最後に追加できることを示すことですので、どの場合でも機能します。ファイルが既に存在FileStreamFileMode.Createているという例外が発生しないようにしたいので、私はすべてに使用するシステムを信用しません。特に、コンテンツを消去して、を介して追加しない場合は特にそうですFileMode.Open。私にとっては、FileStream問題のファイルを削除してから書き込みを行って初めて実際に機能します。をFile.Create開いたままにしてロックしているので、それを追加.Close()することが私のシナリオとSOを処理するための唯一の現実的な方法のようです。
vapcguy 2016年

25

テキストファイルを作成するときは、次のコードを使用できます。

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

コメントのコードを使用します。作成したファイル(ストリーム)を閉じる必要があります。File.Createは、作成したファイルにファイルストリームを返します。

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 
}

私には近い選択肢がないようです。コードは次のとおりです。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)){//テキストを書き込む}
Brett

File.Create戻りFileStream、それはClose()
Null Head

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

7
Stackoverflowへようこそ。少なくともあなたの答え/解決策を説明する短い説明を書くべきです。
Paresh Mayani 2014年

9

File.CreateはFileStreamを返します。ファイルに書き込んだら、それを閉じる必要があります。

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

を使用してファイルを自動的に閉じることができます。


OPはStreamWriteras を開こうとしていますが、の使用から推測できますFile.AppendText
binki

8

コードスニペットで質問を更新しました。適切にインデントすると、すぐに問題が何であるかが明らかになります。使用するFile.Create()が閉じないでくださいFileStream

そのようにすることは不必要であり、StreamWriterすでに存在するファイルに追加し、まだ存在しない場合は新しいファイル作成することをすでに許可しています。このような:

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

これはこのStreamWriterコンストラクタを使用しいます。


1

この質問はすでに回答されていますが、ディレクトリが存在するかどうかを確認し、テキストファイルが存在する場合は末尾に番号を追加する実際のソリューションを次に示します。私が書いたWindowsサービスで毎日ログファイルを作成するためにこれを使用します。これが誰かのお役に立てば幸いです。

// 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

これは古い質問であることはわかっていますが、まだ使用できるようにこれを捨ててFile.Create("filename")"、追加.Dispose()するだけです。

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

このようにして、次のプロセスで使用するためにファイルを作成して閉じます。


1
File.Create(FilePath).Close();上記の答えから、this.Dispose(true); GC.SuppressFinalize((object) this);その実装にあります。
Ghukas

1

この例外の理由はわかっていると思います。このコードスニペットを複数のスレッドで実行している可能性があります。


。私にとって、私は別のスレッドで(asyncronの途中でログファイルを書き込むという問題があった。()目的に待たずにTask.Runを()、および同一ファイルにこの原因マルチスレッドアクセス
ベンスVégert

-1

これを試してください:どのような場合でも機能します。ファイルが存在しない場合は、作成してから書き込みます。そして、すでに存在する場合、問題なく開いてそれに書き込みます:

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
を使用すると、Disposeを呼び出してファイルを閉じます。サンプルファイルで2回閉じられました
バレンタインザハレンコ2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.