2011-01-06 82 views
1

我有一個小問題。我的應用程序要做的是,爲擴展名爲'.XSD'的任何新複製文件查看文件夾,打開文件並將行分配給數組。之後,應該將數組中的數據插入到MySQL數據庫中,然後將使用過的文件移動到另一個文件夾(如果已完成)。C#IOException:進程無法訪問文件,因爲它正在被另一個進程使用

問題是,應用程序對第​​一個文件工作正常,但一旦下一個文件被複制到文件夾,我得到這個異常,例如:'進程無法訪問文件'C:\ inetpub \ admission \ file2.XPD',因爲它正被另一個進程使用'。

如果同時複製了其他手上的兩個文件,則完全沒有問題。

下面的代碼是在主窗口中:

public partial class Form1 : Form 
{ 
    static string folder = specified path;   
    static FileProcessor processor; 

    public Form1() 
    { 
     InitializeComponent(); 
     processor = new FileProcessor(); 
     InitializeWatcher(); 
    } 

    static FileSystemWatcher watcher; 

    static void InitializeWatcher() 
    { 
     watcher = new FileSystemWatcher(); 
     watcher.Path = folder; 

     watcher.Created += new FileSystemEventHandler(watcher_Created); 
     watcher.EnableRaisingEvents = true; 
     watcher.Filter = "*.XPD"; 
    } 

    static void watcher_Created(object sender, FileSystemEventArgs e) 
    { 
     processor.QueueInput(e.FullPath); 
    } 

}

正如你可以看到該文件的路徑輸入到處理隊列這是對所謂的FileProcessor另一個類:

class FileProcessor 
{ 
    private Queue<string> workQueue; 
    private Thread workerThread; 
    private EventWaitHandle waitHandle; 

    public FileProcessor() 
    { 
     workQueue = new Queue<string>(); 
     waitHandle = new AutoResetEvent(true); 
    } 

    public void QueueInput(string filepath) 
    { 
     workQueue.Enqueue(filepath); 

     if (workerThread == null) 
     { 
      workerThread = new Thread(new ThreadStart(Work)); 
      workerThread.Start(); 
     } 

     else if (workerThread.ThreadState == ThreadState.WaitSleepJoin) 
     { 
      waitHandle.Set(); 
     } 
    } 

    private void Work() 
    { 
     while (true) 
     { 
      string filepath = RetrieveFile(); 

      if (filepath != null) 
       ProcessFile(filepath); 
      else 
       waitHandle.WaitOne(); 
     } 
    } 

    private string RetrieveFile() 
    { 
     if (workQueue.Count > 0) 
      return workQueue.Dequeue(); 
     else 
      return null; 
    } 

    private void ProcessFile(string filepath) 
    { 
     string xName = Path.GetFileName(filepath); 
     string fName = Path.GetFileNameWithoutExtension(filepath); 

     string gfolder = specified path;    
     bool fileInUse = true; 
     string line; 
     string[] itemArray = null; 
     int i = 0; 


     #region Declare Db variables 

     //variables for each field of the database is created here 

     #endregion 


     #region Populate array 

     while (fileInUse == true) 
     { 
      FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read,   
              FileShare.ReadWrite); 

      StreamReader reader = new StreamReader(fs); 

      itemArray = new string[75]; 

      while (!reader.EndOfStream == true) 
      { 
       line = reader.ReadLine(); 
       itemArray[i] = line; 
       i++; 
      } 
      fs.Flush(); 
      reader.Close(); 
      reader.Dispose(); 
      i = 0; 
      fileInUse = false; 
     } 

     #endregion 

     #region Assign Db variables 

     //here all the variables get there values from the array 

     #endregion 

     #region MySql Connection 

     //here the connection to mysql is made and the variables are inserted into the db 

     #endregion 

     #region Test and Move file 

     if (System.IO.File.Exists(gfolder + xName)) 
     { 
      System.IO.File.Delete(gfolder + xName); 
     } 

     Directory.Move(filepath, gfolder + xName); 

     #endregion 

    } 
} 

我得到的問題出現在Populate數組區域中。我讀了很多其他線程,並導致相信通過刷新文件流將有助於...

我也想添加一個try..catch爲文件過程是否成功,文件被移動到gfolder如果它失敗了,搬到bfolder

任何幫助將是真棒

的Tx

+0

看起來像某種形式的競爭條件。 當VS在異常中斷時,檢入View-> Debug-> Threads,看看是否還有一個文件正在使用中。 編輯:另外,FileStream不處理,嘗試把它放在一個使用{...} – DaveShaw 2011-01-06 23:49:25

+0

不是我有什麼想法是什麼問題,但只是爲了澄清其他人:什麼時候你確實得到異常?使用閱讀器時? – Stefan 2011-01-06 23:49:57

回答

3

你不處置您的FileStream實例,所以鎖仍保留在文件中。更改代碼中使用using塊:

using (var fileStream = new FileStream(...)) 
{ 
    using (var reader = new StreamReader(fileStream)) 
    { 

    } 
} 

這些using塊將確保實例正確處置。

另外,你爲什麼要在文件流上調用Flush?你不寫任何事的......

0

我建議: 1°,用使用語法上的StreamReader 2°,用使用語法上的FileStream

相關問題