File sedang digunakan oleh proses lain setelah menggunakan File.Create ()

117

Saya mencoba mendeteksi apakah file ada saat runtime, jika tidak, buatlah. Namun saya mendapatkan kesalahan ini ketika saya mencoba menuliskannya:

Proses tidak dapat mengakses file 'myfile.ext' karena sedang digunakan oleh proses lain.

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 
}

Ada ide tentang cara memperbaikinya?

Brett
sumber

Jawaban:

112

The File.Createmetode menciptakan file dan membuka FileStreamfile tersebut. Jadi file Anda sudah terbuka. Anda tidak benar-benar membutuhkan file tersebut. Buat metode sama sekali:

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

Boolean dalam StreamWriterkonstruktor akan menyebabkan konten ditambahkan jika file tersebut ada.

Chris Dunaway
sumber
saya mencoba kode di atas tetapi saya mendapatkan kesalahan yang sama ketika file dibuat dan ketika mencoba untuk menulis ke file itu menunjukkan file sedang digunakan oleh proses lain.
Anmol Rathod
@AnmolRathod pastikan Anda tidak menggunakan File.Create()metode! Potongan di atas sudah membuat file!
Daniel Eisenreich
138
    File.Create(FilePath).Close();
    File.WriteAllText(FileText);

Saya ingin memperbarui jawaban ini untuk mengatakan bahwa ini sebenarnya bukan cara paling efisien untuk menulis semua teks. Anda hanya boleh menggunakan kode ini jika Anda membutuhkan sesuatu yang cepat dan kotor.

Saya adalah seorang programmer muda ketika saya menjawab pertanyaan ini, dan saat itu saya pikir saya adalah seorang jenius karena memberikan jawaban ini.

Carsen Daniel Yates
sumber
4
Saya suka bagaimana semua jawaban lain terlalu rumit. Orang tidak menyadari bahwa ada jawaban yang lebih sederhana untuk setiap masalah.
Carsen Daniel Yates
14
Kelemahan dari kode ini adalah tidak perlu membuka file dua kali. Selain itu, tidak terlalu perlu untuk memeriksa apakah file tersebut ada sama sekali, karena konstruktor FileStream akan secara otomatis membuatnya untuk Anda jika tidak ada, kecuali jika Anda secara eksplisit melarangnya.
reirab
2
@ reirab Ini sepenuhnya relatif. Saya perlu memeriksa apakah file tersebut ada dan jika ada, hapus dan buat lagi, jadi jawaban ini lebih disukai dalam kasus saya.
makoshichi
1
@ SO Maka Anda memiliki masalah yang berbeda dari OP, hanya yang terkait. Selain itu, dalam kasus Anda, Anda masih dapat menggunakan FileStream(string, FileMode)konstruktor dan meneruskannya ke FileMode.Create , yang akan menimpa file yang ada. Masih tidak perlu membuka file dua kali. Juga, jawaban ini diedit setelah saya memposting komentar asli saya.
reirab
2
Inti dari jawaban ini adalah untuk menunjukkan bahwa Anda dapat menambahkan .Close()di akhir, sehingga berfungsi dalam hal apa pun. Saya tidak mempercayai sistem yang menggunakan FileStreamuntuk semuanya karena saya tidak ingin pengecualian terjadi FileMode.Createkarena file tersebut sudah ada di sana - terutama ketika saya ingin menghapus isinya dan tidak menambahkannya FileMode.Open. Bagi saya, FileStreamhanya benar-benar berfungsi setelah menyingkirkan file yang dipermasalahkan, lalu menulis ke sana. Karena File.Createmembiarkannya terbuka dan terkunci, tampaknya menambahkannya .Close()adalah satu-satunya cara nyata untuk menangani skenario saya dan SO.
vapcguy
25

Saat membuat file teks Anda dapat menggunakan kode berikut:

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

Menggunakan kode dari komentar Anda. File (aliran) yang Anda buat harus ditutup. File.Create mengembalikan filestream ke file yang baru saja dibuat .:

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
sumber
Sepertinya saya tidak punya pilihan dekat. Berikut kodenya: string filePath = string.Format (@ "{0} \ M {1} .dat", ConfigurationManager.AppSettings ["DirectoryPath"], costCentre); if (! File.Exists (filePath)) {File.Create (filePath); } menggunakan (StreamWriter sw = File.AppendText (filePath)) {// write my text}
Brett
File.Createkembali FileStreamdan yang memilikiClose()
Null Head
15
FileStream fs= File.Create(ConfigurationManager.AppSettings["file"]);
fs.Close();
pengguna3430377
sumber
7
Selamat datang di Stackoverflow. Anda setidaknya harus menulis deskripsi singkat untuk menggambarkan jawaban / solusi Anda.
Paresh Mayani
9

File.Create mengembalikan FileStream. Anda harus menutupnya ketika Anda telah menulis ke 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);
        }

Anda dapat menggunakan menggunakan untuk menutup file secara otomatis.

kimtiede
sumber
Padahal OP mencoba membuka file StreamWriter seperti yang bisa disimpulkan dari penggunaannya File.AppendText.
binki
8

Saya memperbarui pertanyaan Anda dengan cuplikan kode. Setelah indentasi yang tepat, segera jelas apa masalahnya: Anda menggunakan File.Create()tetapi tidak menutup FileStreamyang dikembalikan.

Melakukannya dengan cara itu tidak perlu, StreamWritersudah memungkinkan untuk menambahkan file yang sudah ada dan membuat file baru jika belum ada. Seperti ini:

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

Yang menggunakan konstruktor iniStreamWriter .

Hans Passant
sumber
1

Pertanyaan ini telah dijawab, tetapi berikut adalah solusi dunia nyata yang memeriksa apakah direktori tersebut ada dan menambahkan angka di akhir jika file teks ada. Saya menggunakan ini untuk membuat file log harian pada layanan Windows yang saya tulis. Saya harap ini membantu seseorang.

// 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();
    }
}
Tenang
sumber
1

Saya tahu ini adalah pertanyaan lama, tapi saya hanya ingin membuang ini ke sana yang masih bisa Anda gunakan File.Create("filename")", tambahkan .Dispose()saja.

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

Dengan cara ini ia membuat dan menutup file untuk proses selanjutnya untuk menggunakannya.

Saya Batman
sumber
1
File.Create(FilePath).Close();dari jawaban di atas ada this.Dispose(true); GC.SuppressFinalize((object) this);dalam implementasinya.
Ghukas
1

Saya rasa saya tahu alasan pengecualian ini. Anda mungkin menjalankan cuplikan kode ini di beberapa utas.

Kusala Subasinghe
sumber
Bagi saya adalah masalah ketika saya menulis file log dengan cara asyncron (di utas berbeda: Task.Run () tanpa menunggu (sengaja), dan ini menyebabkan akses multithread ke file yang sama.
Bence Végert
-1

Coba ini: Bagaimanapun, ini berfungsi, jika file tidak ada, itu akan membuatnya dan kemudian menulis ke sana. Dan jika sudah ada, tidak masalah itu akan terbuka dan menulis padanya:

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
sumber
1
menggunakan akan menutup file dengan panggilan Buang. Dalam file sampel Anda ditutup dua kali
Valentine Zakharenko