【问题标题】:C# IOException: The process cannot access the file because it is being used by another processC# IOException:该进程无法访问该文件,因为它正被另一个进程使用
【发布时间】:2011-01-07 08:17:25
【问题描述】:

我有一个小问题。我的应用程序应该做的是观察一个文件夹,以查看任何带有扩展名“.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

    }
}

我遇到的问题发生在填充数组区域中。我阅读了很多其他线程,并被引导相信通过刷新文件流会有所帮助......

我也在考虑添加一个 try..catch,如果文件处理成功,文件将移动到 gfolder,如果失败,则移动到 bfolder

任何帮助都会很棒

发送

【问题讨论】:

  • 看起来像是某种竞争条件。当 VS 在异常上中断时,检查 View->Debug->Threads 并查看是否还有另一个文件仍在使用中。编辑:另外,FileStream 没有被释放,尝试把它放在 using {...}
  • 并不是说我不知道​​问题出在哪里,只是为了向其他人澄清:你什么时候得到异常?什么时候使用阅读器?
  • 不确定 while (fileInUse == true) 语句。在此处尝试使用 using(FileStream fs = FileStream(...)) 语句。

标签: c# .net


【解决方案1】:

您没有处理您的 FileStream 实例,因此文件上仍保留一个锁。更改您的代码以使用 using 块:

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

    }
}

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

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

【讨论】:

  • 或更简洁:using (var reader = File.OpenText(path)) { ... }
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2018-09-20
    • 2020-03-11
    • 1970-01-01
    • 1970-01-01
    • 2023-01-17
    • 1970-01-01
    • 2010-12-10
    相关资源
    最近更新 更多