无法移动文件,因为它被另一个进程使用 - 我的程序?

时间:2010-04-17 16:25:15

标签: c# file directory

我的程序无法File.MoveFile.Delete一个文件,因为它正被“另一个进程”使用,但它实际上是我自己的程序正在使用它。

我使用Directory.GetFiles来初始获取文件路径,然后我通过简单地查看其名称和处理信息来处理文件。 因此,我正在做的就是使用字符串本身,对吧?之后,我尝试将文件移动到“Handled”目录。几乎所有人都会移动,但有时他们根本不会,因为他们被我的程序使用。

为什么他们中的大多数都会移动但是一两个坚持?我可以做些什么来尝试释放文件?没有溪流可以关闭。

编辑这里是一些代码:

public object[] UnzipFiles(string[] zipFiles)
    {
        ArrayList al = new ArrayList(); //not sure of proper array size, so using arraylist
        string[] files = null;

        for (int a = 0; a < zipFiles.Length; a++)
        {
            string destination = settings.GetTorrentSaveFolder() + @"\[CSL]--Temp\" + Path.GetFileNameWithoutExtension(zipFiles[a]) + @"\";
            try
            {
                fz.ExtractZip(zipFiles[a], destination, ".torrent");

                files = Directory.GetFiles(destination, 
                    "*.torrent", SearchOption.AllDirectories);

                for (int b = 0; b < files.Length; b++)
                    al.Add(files[b]);
            }

            catch(Exception e)
            {}
        }

        try
        {
            return al.ToArray(); //return all files of all zips
        }
        catch (Exception e)
        {
            return null;
        }
    }

这来自:

try
                {
                    object[] rawFiles = directory.UnzipFiles(zipFiles);
                    string[] files = Array.ConvertAll<object, string>(rawFiles, Convert.ToString);
                    if (files != null)
                    {
                        torrents = builder.Build(files);
                        xml.AddTorrents(torrents);
                        directory.MoveProcessedFiles(xml);
                        directory.MoveProcessedZipFiles();
                    }
                }
                catch (Exception e)
                { }

因此,构建器构建了Torrent类的对象。然后我将类Torrent的对象添加到xml文件中,该文件存储有关它的信息,然后我尝试移动使用xml文件的已处理文件作为每个文件所在位置的参考。

尽管大部分文件都能正常工作,但我会得到一个IOException,它最终会被另一个进程使用:

public void MoveProcessedZipFiles()
    {
        string[] zipFiles = Directory.GetFiles(settings.GetTorrentSaveFolder(), "*.zip", SearchOption.TopDirectoryOnly);

        if (!Directory.Exists(settings.GetTorrentSaveFolder() + @"\[CSL] -- Processed Zips"))
            Directory.CreateDirectory(settings.GetTorrentSaveFolder() + @"\[CSL] -- Processed Zips");

        for (int a = 0; a < zipFiles.Length; a++)
        {
            try
            {
                File.Move(zipFiles[a], settings.GetTorrentSaveFolder() + @"\[CSL] -- Processed Zips\" + zipFiles[a].Substring(zipFiles[a].LastIndexOf('\\') + 1));
            }
            catch (Exception e)
            {
            }
        }
    }

3 个答案:

答案 0 :(得分:2)

根据您的评论,这真的闻起来像手柄泄漏。然后,查看您的代码,fz.ExtractZip(...)看起来像是使用文件句柄的最佳候选者,因此会泄漏它们。

代码的fz部分类型或第三方库是?如果它在您的代码中,请确保它关闭所有句柄(最安全的方法是通过usingtry - finally块)。如果它是第三方库的一部分,请检查文档并查看是否需要进行任何类型的清理。它很可能实现IDisposable;在这种情况下,将其使用放在using块内或确保其妥善处理。

catch(Exception e) {}是非常糟糕的做法。当你确切地知道可能抛出什么异常并且为什么你想忽略它时,你应该只以这种方式摆脱异常。如果程序无法处理的异常发生,最好是使用描述性错误消息和有价值的调试信息(例如:异常类型,堆栈跟踪等)崩溃,而不是忽略问题并继续,好像什么都没有消失错误,因为异常意味着某些东西肯定出错了

长话短说,调试程序的最快方法是:

  1. 将您的通用catch替换为finally
  2. 将任何相关的清理代码添加/移动到finally
  3. 注意你得到的任何例外:它抛出的形式在哪里?它是什么样的例外?什么文档或代码评论说投掷它的方法?等等。
  4. 要么
    4.1。如果fz的类型是您的代码的一部分,请在那里查找泄漏 4.2。如果它是第三方库的一部分,请查看文档(并考虑获得作者的支持)。
  5. 希望这有帮助

答案 1 :(得分:0)

这意味着什么:“没有溪流可以关闭”?你的意思是你不使用溪流或关闭它们? 我相信你有一些开放的流 你有一些使用这个文件的静态类吗? 1.尝试编写简单的应用程序,只解析移动和删除文件,看看这是否有效 2.在这里写下一些与你的文件一起使用的代码片段 3.尝试使用unlocker确保两次没有任何其他使用这些文件的东西:http://www.emptyloop.com/unlocker/(不要忘记检查病毒文件:))

答案 2 :(得分:0)

Path正在处理多个文件以获取他们的文件名。尽管在复制相同问题时未能成功,但在我的程序“处理”阶段结束时使用GC.Collect强制进行垃圾收集已成功解决问题。

再次感谢所有帮助过的人。我学到了很多东西。