C#IOException异常:因为它正由另一个进程使用的进程无法访问该文件 [英] C# IOException: The process cannot access the file because it is being used by another process

查看:1431
本文介绍了C#IOException异常:因为它正由另一个进程使用的进程无法访问该文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小问题。什么我的应用程序是supose做的,是看一个文件夹与延伸任何新复制的文件'.XSD打开文件并分配线阵列。后,从该阵列中的数据应该插入MySQL数据库,那么使用的文件移动到另一文件夹,如果它的完成。

I have a slight problem. What my application is supose to do, is to watch a folder for any newly copied file with the extention '.XSD' open the file and assign the lines to an array. After that the data from the array should be inserted into a MySQL database, then move the used file to another folder if it's done.

现在的问题是,该应用程序的第一个文件工作正常,但只要下一个文件复制到我得到这个例外,例如文件夹:该进程无法访问该文件'C:\的Inetpub \录取\ file2.XPD',因为它正由另一个进程。

The problem is that the application works fine with the first file, but as soon as the next file is copied to the folder I get this exception for example: 'The process cannot access the file 'C:\inetpub\admission\file2.XPD' because it is being used by another process'.

如果在onther手两个文件复制在同一时间没有任何问题的。

If two files on the onther hand is copied at the same time there's no problem at all.

下面code是在主窗口:

The following code is on the main window:

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:

As you can see the file's path is entered into a queue for processing which is on another class called 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

    }
}

我得到的问题发生在填充阵列区域。我看了其他线程的很多,是导致相信,通过刷新文件流将有助于...

The problem I get occurs in the Populate array region. I read alot of other threads and was lead to believe that by flushing the file stream would help...

我还想到将在try..catch因为如果该文件的过程是成功的,该文件被移动到gfolder,如果它失败了,搬到bfolder

I am also thinking of adding a try..catch for if the file process was successful, the file is moved to gfolder and if it failed, moved to bfolder

任何帮助将是真棒

的Tx

推荐答案

你不处理你的的FileStream 实例,所以锁保留在文件中。改变你的code使用使用块:

You're not disposing of your FileStream instance, so a lock remains on the file. Change your code to use using blocks:

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

    }
}

这些使用块将确保实例正确处置。

These using blocks will ensure the instances are correctly disposed of.

此外,你为什么叫刷新的文件流?你不写任何与它...

Also, why are you calling Flush on the file stream? You're not writing anything with it...

这篇关于C#IOException异常:因为它正由另一个进程使用的进程无法访问该文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆