C#IOException:进程无法访问该文件,因为它正由另一个进程使用

时间:2011-01-06 23:42:12

标签: c# .net

我有一个小问题。我的应用程序要做的是观察任何新复制文件的文件夹,并使用扩展名“.XSD”打开文件并将行分配给数组。之后,应将数组中的数据插入MySQL数据库,然后将已使用的文件移动到另一个文件夹中。

问题是应用程序与第一个文件一起工作正常,但是一旦将下一个文件复制到该文件夹​​,我就会遇到此异常,例如:'进程无法访问文件'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

2 个答案:

答案 0 :(得分:3)

您没有丢弃FileStream实例,因此文件上仍有锁。将代码更改为使用using块:

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

    }
}

这些using块将确保正确处理实例。

另外,为什么要在文件流上调用Flush?你不是用它写任何东西......

答案 1 :(得分:0)

我建议: 1°使用StreamReader上的using语法 2°使用FileStream上的using语法