2011-01-06 80 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

相关问题