显示目录中的每个文件,但不显示当前正在复制的文件

时间:2013-07-19 20:53:53

标签: c# file

我有一个函数可以检查目录中的每个文件并将列表写入控制台。问题是,我不希望它包含当前正被复制到目录的文件,我只希望它显示完整的文件。我怎么做?这是我的代码:

foreach (string file in Directory.EnumerateFiles("C:\folder"))
        {
            Console.WriteLine(file);
        }

3 个答案:

答案 0 :(得分:3)

真的没有办法告诉“被复制”与“被某事物写入锁定”。相关:How to check for file lock?Can I simply 'read' a file that is in use?

如果您只想显示未打开的文件列表,可以尝试打开它们:

foreach (string file in Directory.EnumerateFiles("C:\folder"))
{
   try {
     using (var file = file.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) {
       Console.WriteLine(file);
     }
   } catch {
     // file is in use
     continue;
   }
}

然而 - 很多警告。

  • 显示文件名后(using块的结尾),文件可以立即打开
  • 编写文件的过程可能使用了FileShare.Read,这意味着尽管被写入,呼叫仍会成功。

我不确定你到底在做什么,但听起来有两个进程共享一个队列目录:一个写入,一个读取/处理。最大的挑战是编写文件需要花费时间,因此您的“阅读”过程最终会在整个文件出现之前将其读取并尝试读取,这将取决于共享模式,应用程序如何以某种方式失败写等等。

处理这种情况的常见模式是使用像Move这样的原子文件操作:

  • 对(相同文件系统(非常重要)的临时目录执行(慢速)写入/复制操作作为队列目录
  • 完成后,执行从临时目录移动到队列目录。

由于move是原子的,文件将不在那里,或者它将100%存在 - “阅读”过程没有机会在部分存在时看到文件。

请注意,如果您跨文件系统进行移动,则其行为与副本相同。

答案 1 :(得分:1)

没有“正在复制的当前文件”列表存储在Windows / .NET /中的任何位置。您可能做的最多的事情就是尝试打开每个文件以进行追加,看看是否有异常。根据目录的大小和位置以及安全设置,这可能不是一个选项。

答案 2 :(得分:1)

没有一种干净的方法可以做到这一点,但这......工作......

foreach (var file in new DirectoryInfo(@"C:\Folder").GetFiles())
{
    try
    {
        file.OpenRead();
    }
    catch
    {
        continue;
    }
    Console.WriteLine(file.Name);
}