2015-06-22 70 views
3

我有一個移動項目,用於監視患者的操作並將結果寫入文本文件。當我正在試驗輸出時,我只是讓文件保存在Debug文件夾中,這很好。但是,現在我創建了一個完整的目錄,用於創建或打開主文件夾,然後創建一個子文件夾(基於程序中的輸入文本),以將文本文件保存到。IO異常 - 正在被另一個進程使用的文件(在創建目錄後無法打開文件)

private void createDirectory() 
    { //create output file in this folder using owner name and current date 

     //main folder path (contains all files output from system) 
     string rootDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\Horse Monitoring Records"; 
     //sub folder path (each patient has individual subfolder) 
     string subDirectory = rootDirectory + "\\" + txtPatName.Text + "-" + txtOwnerName.Text; 
     //file name (patient has file created for each operation) 
     fileName = subDirectory + "\\" + txtOwnerName.Text + "-" + DateTime.Now.Date.ToString("ddMMyyyy") + ".txt"; 

     if (!Directory.Exists(rootDirectory)) //if main folder does not exist... 
     { 
      Directory.CreateDirectory(rootDirectory); //create it in My Documents 
     } 
     if (!Directory.Exists(subDirectory)) //if patient sub folder does not exist... 
     { 
      Directory.CreateDirectory(subDirectory); //create it in Patient-Owner format 
     } 
     if (!File.Exists(fileName)) //if monitoring file does not exist... 
     { 
      File.Create(fileName); //create it in Owner-Date format 
     } 
    } 

這一階段工作正常,但只要你嘗試一些數據保存到文本文件,它拋出一個運行時錯誤,指出

文件無法訪問,因爲它是被另一個進程使用。

的異常長大這裏:

private void saveFileDetails() 
    { 
     //Once case details have been entered, create new file using these details and add data input structure 
     StreamWriter consoleFile = new StreamWriter(fileName); 
    ... 
    } 

當我去檢查了該文件夾,在相關子文件夾和文件已經被創建,但文本文件是空白的。 我猜這是在創建目錄後關閉文本文件,這意味着當系統嘗試打開它時它已經打開。我無法弄清楚如何排除這個問題!

上面所示的兩個函數的調用是這樣的:

private void btnStart_Click(object sender, EventArgs e) 
    { 
     ... 

     //file details entered upon load written to new file - according to PatID 
     createDirectory(); 
     saveFileDetails(); 
    } 

在哪裏何去何從任何建議將非常感謝!

謝謝, 馬克

+0

如果在'File.Create(fileName)'之後立即寫入,操作系統可能尚未釋放該文件。不用檢查文件是否存在,你可以使用以FileXXXX枚舉參數爲參數的'StreamWriter'重載。 – cubrr

+0

我的不好,你需要使用FileStream並將其傳遞給StreamWrifer。 – cubrr

+0

您不需要將FileStream傳遞給StreamWriter。在傳遞文件路徑的構造函數中存在重載,如果該文件存在,則會打開文件,如果不存在,則會創建該文件。看到這裏:https://msdn.microsoft.com/en-us/library/fysy0a4b%28v=vs.100%29.aspx – Jauch

回答

1

這裏的問題是,你

if (!File.Exists(fileName)) //if monitoring file does not exist... 
{ 
    File.Create(fileName); //create it in Owner-Date format 
} 

右鍵嘗試寫入文件之前。由於您剛剛創建了它(如果它不存在),因此操作系統可能尚未發佈該文件。

就像評論中提到的@Jauch一樣,你可以完全跳過這個檢查,並使用StreamWriter重載,如果它不存在,將會創建文件,或者如果它附加到它,則會附加到該文件。

private void saveFileDetails() 
{ 
    //Once case details have been entered, create new file using these details and add data input structure 
    using (StreamWriter consoleFile = new StreamWriter(fileName, true)) 
    { 
     // ... 
    } 
} 

或者您可以使用以下方法來一次編寫所有文字:

File.AppendAllText(textToWrite, fileName); 
+0

這已經得到它了,謝謝! – marcuthh

0

StreamWriter實現IDisposable,所以它包裹在使用塊可以管理的關閉和處置的作家,並確保它是可你要摸該文件的下一次。它也可以管理創建文本文件,如果它不存在,則不需要明確調用File.Create

StreamWriter consoleFile = new StreamWriter(fileName); 

成爲

using (StreamWriter writer = File.AppendText("log.txt")) 
{ 
    // writing, etc. 
} 

using (StreamWriter writer = new StreamWriter(fileName, true)) 
{ // true says "append to file if it exists, create if it doesn't" 
    // writing, etc. 
} 

無論看起來更具可讀性,你將正常工作。

1

File.Create(fileName)返回一個打開的流哪個是永遠不會關閉該文件。

要創建一個空文件使用File.WriteAllBytes(fileName, new byte[0]);

否則2種方法可以shortend

private void SaveFileDetails() 
{ 
    string subDirectory = Path.Combine(
     Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), 
     "Horse Monitoring Records"); 

    // create the folder hierarchy if not exists. does nothing if already there 
    Directory.CreateDirectory(subDirectory); 

    // each patient has individual file 
    var filepath = Path.Combine(subDirectory, 
     txtPatName.Text + "-" + txtOwnerName.Text + "-" + DateTime.Now.Date.ToString("yyyyMMdd") + ".txt"); 

    // creates the file if not exists 
    using (var writer = new StreamWriter(filepath, append: true, encoding: Encoding.UTF8)) 
    { 
     // write details 
    } 
} 

注:

  • 合併2種方法
  • .NET命名約定適用
  • 更改dateformat以更好地排序b y名稱在資源管理器中
相關問題