File.Create () kullanıldıktan sonra başka bir işlem tarafından kullanılan dosya


118

Çalışma zamanında bir dosya olup olmadığını tespit etmeye çalışıyorum, yoksa onu oluşturun. Ancak yazmaya çalıştığımda şu hatayı alıyorum:

İşlem, başka bir işlem tarafından kullanıldığından 'myfile.ext' dosyasına erişemiyor.

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 
}

Nasıl düzelteceğimize dair bir fikri olan?

Yanıtlar:


112

File.CreateYöntem dosya oluşturur ve bir açılır FileStreamdosyada. Yani dosyanız zaten açık. Dosyaya gerçekten ihtiyacınız yok. Yöntem oluştur:

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

Yapıcıdaki boole StreamWriter, dosya varsa içeriğin eklenmesine neden olur.


Yukarıdaki kodu denedim ancak dosya oluşturulduğunda aynı hatayı alıyorum ve dosyaya yazmaya çalıştığında dosyanın başka bir işlem tarafından kullanıldığını gösteriyor.
Anmol Rathod

@AnmolRathod File.Create()yöntemi kullanmadığınızdan emin olun ! Yukarıdaki kod parçası zaten dosyayı oluşturuyor!
Daniel Eisenreich

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

Tüm metni yazmanın gerçekten en verimli yolu olmadığını söylemek için bu yanıtı güncellemek istiyorum. Bu kodu yalnızca hızlı ve kirli bir şeye ihtiyacınız olduğunda kullanmalısınız.

Bu soruyu cevapladığımda genç bir programcıydım ve o zamanlar bu cevabı bulduğum için bir tür dahi olduğumu düşündüm.


4
Diğer tüm cevapların çok karmaşık olmasına bayılıyorum. İnsanlar her sorunun daha basit bir cevabı olduğunun farkında değiller.
Carsen Daniel Yates

14
Bu kodun dezavantajı, dosyayı gereksiz yere iki kez açmasıdır. Ayrıca, dosyanın var olup olmadığını kontrol etmek gerçekten gerekli değildir, çünkü FileStream yapıcısı, siz açıkça yapmamasını söylemediğiniz sürece, dosya yoksa sizin için otomatik olarak oluşturacaktır.
reirab

2
@reirab Bu tamamen görecelidir. Dosyanın var olup olmadığını kontrol etmem gerekiyor ve varsa silip yeniden oluşturmam gerekiyor, bu yüzden benim durumumda bu cevap tercih ediliyor.
makoshichi

1
@SO O zaman OP'den farklı bir probleminiz var, sadece ilgili bir problem. Ayrıca, sizin durumunuzda, sadece yapıcıyı kullanabilir ve mevcut herhangi bir dosyanın üzerine yazacak olan FileMode.Create'iFileStream(string, FileMode) geçebilirsiniz . Yine de dosyayı iki kez açmanıza gerek yok. Ayrıca, bu cevap orijinal yorumumu gönderdikten sonra düzenlendi.
reirab

2
Bu cevabın amacı .Close(), sonuna kadar ekleyebileceğinizi göstermektir , böylece her durumda işe yarar. Her FileStreamşey için kullanma sistemine güvenmiyorum çünkü istisnanın FileMode.Createdosyanın zaten orada olmasını istemiyorum - özellikle içeriği temizlemek ve bunlara ekleme yapmak istemediğimde FileMode.Open. Bana göre, FileStreamsadece söz konusu dosyadan kurtulduktan sonra gerçekten işe yarıyor, sonra ona yazıyor. Yana File.Createo açık ve kilitli ayrılıyor, bu ekleme görünüyor .Close()benim senaryo ve SO en başa çıkmanın tek gerçek yoludur için.
vapcguy

25

Bir metin dosyası oluştururken aşağıdaki kodu kullanabilirsiniz:

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

Yorumunuzdaki kodu kullanmak. Oluşturduğunuz dosya (akış) kapatılmalıdır. File.Create dosya akışını yeni oluşturulan dosyaya döndürür .:

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 
}

Yakın bir seçeneğim yok gibi görünüyor. Kod şu şekildedir: string filePath = string.Format (@ "{0} \ M {1} .dat", ConfigurationManager.AppSettings ["DirectoryPath"], costCentre); eğer (! File.Exists (filePath)) {File.Create (filePath); } kullanarak (StreamWriter sw = File.AppendText (filePath)) {// metnimi yaz}
Brett

File.Creategeri döndü FileStreamve bu varClose()
Null Head

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

7
Stackoverflow'a hoş geldiniz. Cevabınızı / çözümünüzü açıklamak için en azından kısa bir açıklama yazmalısınız.
Paresh Mayani

9

File.Create bir FileStream döndürür. Dosyaya yazdığınızda bunu kapatmanız gerekir:

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

Dosyayı otomatik olarak kapatmak için kullanabilirsiniz.


OP, StreamWriterkullanımından anlaşılacağı gibi bir açmaya çalışıyor olsa da File.AppendText.
binki

8

Sorunuzu kod parçacığı ile güncelledim. Düzgün girinti yaptıktan sonra sorunun ne olduğu hemen anlaşılır: kullanıyorsunuz File.Create()ama FileStreamdöndüğünü kapatmıyorsunuz .

Bu şekilde yapmak gereksizdir, StreamWriterzaten mevcut bir dosyaya eklenmeye ve henüz yoksa yeni bir dosya oluşturmaya izin verir . Bunun gibi:

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

Hangi kullanan bu StreamWriteryapıcı .


1

Bu soru zaten yanıtlandı, ancak burada dizinin var olup olmadığını kontrol eden ve metin dosyası varsa sonuna bir sayı ekleyen gerçek bir çözüm var. Bunu yazdığım bir Windows hizmetinde günlük günlük dosyaları oluşturmak için kullanıyorum. Umarım bu birine yardımcı olur.

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

Bunun eski bir soru olduğunu biliyorum, ama hala kullanabileceğin bunu oraya atmak istiyorum File.Create("filename")", sadece ekle .Dispose().

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

Bu şekilde, bir sonraki işlemin kullanması için dosyayı oluşturur ve kapatır.


1
File.Create(FilePath).Close();Yukarıdaki cevaba göre this.Dispose(true); GC.SuppressFinalize((object) this);uygulamasında var.
Ghukas

1

Sanırım bu istisnanın nedenini biliyorum. Bu kod parçacığını birden çok iş parçacığında çalıştırıyor olabilirsiniz.


Benim için bir günlük dosyasını eşzamansız bir şekilde (farklı bir iş parçacığında: Task.Run () beklemeden (kasıtlı olarak) yazmam ve bu aynı dosyaya çoklu okuma erişimine neden
oluyordu

-1

Şunu deneyin: Her durumda çalışır, eğer dosya yoksa, onu oluşturur ve sonra ona yazar. Ve eğer zaten varsa, sorun yok, açılacak ve ona yazacak:

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
kullanmak dosyayı Dispose çağırarak kapatır. Örnek dosyanızda iki kez kapatıldı
Valentine Zakharenko
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.