web-dev-qa-db-ja.com

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

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

プロセスは別のプロセスによって使用されているため、ファイル '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 
}

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

107
Brett

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

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

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

106
Chris Dunaway
    File.Create(FilePath).Close();
    File.WriteAllText(FileText);

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

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

131

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

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 
}
25
Ralf de Kleine
FileStream fs= File.Create(ConfigurationManager.AppSettings["file"]);
fs.Close();
16
user3430377

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

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

9
kimtiede

コードスニペットで質問を更新しました。適切にインデントすると、問題がすぐに明らかになります。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 
  }

this StreamWriter constructor を使用します。

8
Hans Passant

これは古い質問ですが、File.Create("filename")"をまだ使用できるので、そこに.Dispose()を追加するだけです。

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

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

1
IamBatman

この質問はすでに回答されていますが、ディレクトリが存在するかどうかを確認し、テキストファイルが存在する場合は末尾に数字を追加する実際のソリューションです。これは、作成した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
Halcyon

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

1

このコードを試してください:

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 
}
0
Jaspal