我有一个函数可以检查目录中的每个文件并将列表写入控制台。问题是,我不希望它包含当前正在复制到目录的文件,我只希望它显示完整的文件。我怎么做?这是我的代码:
foreach (string file in Directory.EnumerateFiles("C:\folder"))
{
Console.WriteLine(file);
}
真的没有办法区分“被复制”和“被某些东西锁定”。相关:如何检查文件锁定?我可以简单地“读取”正在使用的文件吗?
如果您只想显示未打开以供写入的文件列表,您可以通过尝试打开它们来实现:
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
块的末尾)后,文件可以立即被其他东西打开我不确定您到底在做什么,但这听起来像是两个进程共享一个队列目录:一个写入,一个读取/处理。最大的挑战是写入文件需要时间,因此您的“读取”过程最终会在整个文件存在之前将其拾取并尝试读取它,这会以某种方式失败,具体取决于共享模式,您的应用程序如何写的等等。
处理这种情况的常见模式是使用原子文件操作,例如Move
:
由于 move 是原子的,因此文件要么不存在,要么 100% 存在——“读取”过程在文件部分存在时没有机会看到文件。
请注意,如果您跨文件系统进行移动,它将与副本相同。
Windows/.NET/whatever 中的任何位置都没有存储“当前正在复制的文件”列表。可能您最多可以尝试打开每个文件进行追加,看看是否有异常。根据目录的大小和位置以及安全设置,这可能不是一个选项。
没有一种干净的方法可以做到这一点,但这...有效...
foreach (var file in new DirectoryInfo(@"C:\Folder").GetFiles())
{
try
{
file.OpenRead();
}
catch
{
continue;
}
Console.WriteLine(file.Name);
}