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()방법을 사용하지 마십시오 ! 위의 스 니펫은 이미 파일을 생성합니다!
Daniel Eisenreich

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

이 답변을 업데이트하여 이것이 실제로 모든 텍스트를 작성하는 가장 효율적인 방법이 아니라고 말하고 싶습니다. 빠르고 더러운 것이 필요한 경우에만이 코드를 사용해야합니다.

제가이 질문에 답했을 때 저는 젊은 프로그래머 였고, 그때 저는이 대답을 생각 해낸 어떤 천재라고 생각했습니다.


4
나는 다른 모든 대답이 너무 복잡하다는 것을 좋아합니다. 사람들은 모든 문제에 더 간단한 답이 있다는 것을 깨닫지 못합니다.
Carsen Daniel Yates 2011

14
이 코드의 단점은 불필요하게 파일을 두 번 열 수 있다는 것입니다. 또한 파일이 존재하지 않는지 명시 적으로 지시하지 않는 한 FileStream 생성자가 파일이없는 경우 자동으로 생성하므로 파일이 존재하는지 여부를 확인할 필요가 없습니다.
reirab

2
@reirab 이것은 완전히 상대적입니다. 파일이 존재하는지 확인하고 존재하는 경우 삭제하고 다시 생성해야하므로 제 경우에는이 답변이 선호됩니다.
makoshichi

1
@SO 그렇다면 OP와는 다른 문제가 있습니다. 또한 귀하의 경우에는 FileStream(string, FileMode)생성자를 사용하고 FileMode.Create를 전달하면 기존 파일을 덮어 쓸 수 있습니다. 여전히 파일을 두 번 열 필요가 없습니다. 또한이 답변은 원래 댓글을 게시 한 후에 수정되었습니다.
reirab

2
이 대답의 요점은 .Close()끝에 추가 할 수 있으므로 어떤 경우에도 작동한다는 것을 보여주는 것 입니다. 나는 파일이 이미 거기 FileStreamFileMode.Create있다는 예외가 발생하는 것을 원하지 않기 때문에 모든 것을 사용하는 시스템을 신뢰 하지 않습니다. 특히 내용을 지우고 FileMode.Open. 나에게는 FileStream문제의 파일을 제거한 다음 작성해야만 실제로 작동합니다. File.Create열려 있고 잠긴 상태로두기 때문에 .Close()내 시나리오와 SO를 처리하는 유일한 방법 인 것 같습니다 .
vapcguy

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()
널 헤드

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

7
Stackoverflow에 오신 것을 환영합니다. 답변 / 해결 방법을 설명하려면 최소한 간단한 설명을 작성해야합니다.
Paresh Mayani

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

파일을 자동으로 닫기 위해 using을 사용할 수 있습니다.


OP는 StreamWriter그의 사용에서 유추 할 수 있는 대로 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

이 예외의 이유를 알고 있다고 생각합니다. 이 코드 조각을 여러 스레드에서 실행할 수 있습니다.


저에게는 비동기 방식 (다른 스레드에서 : Task.Run ()에서 기다리지 않고 (의도적으로)) 로그 파일을 작성하는 문제가 있었고 이로 인해 동일한 파일에 대한 다중 스레드 액세스가 발생했습니다.
Bence 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를 호출하여 파일을 닫습니다. 샘플 파일에서 두 번 닫힌
발렌타인 Zakharenko
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.