1

目前我尝试改进两个 Windows 服务(C#)的设计。服务 A 生成数据导出(csv 文件)并将它们写入临时目录。所以文件被写入一个临时目录,它是一个子目录。的主输出目录。然后文件被移动(通过File.Move)到输出目录(在成功写入之后)。此导出可能由多个线程执行。

另一个服务 B 尝试在定义的时间间隔内从此输出目录中获取文件。如何确保Directory.GetFiles()排除锁定的文件。

  1. 我是否应该尝试通过创建一个新的 FileStream(使用 () 来检查每个文件,如此Stream stream = new FileStream("MyFilename.txt", FileMode.Open)所述 。

  2. 或者生产者服务 (A) 是否应该使用由消费者服务 (B) 自动排除的临时文件名 (*.csv.tmp) 以及适当的搜索模式。并在移动完成后重命名文件。

  3. 是否有更好的方法来处理此类文件列表操作。
4

2 回答 2

0

一种方法是在使用时将文件标记为来自书写应用程序的临时文件,并且仅在写入并关闭它们后取消标记,例如。

FileStream f = File.Create (filename);
FileAttributes attr = File.GetAttributes (filename);
File.SetAttributes (filename, attr | FileAttributes.Temporary);
 //write to file.
f.Close ();

File.SetAttributes (filename, attr);

从消费应用程序中,您只想跳过任何临时文件。

foreach (var file in Directory.GetFiles (Path.GetDirectoryName (filename))) {
    if ((File.GetAttributes (file) & FileAttributes.Temporary) != 0) continue;
    // do normal stuff.
}
于 2013-02-26T12:20:39.010 回答
0

不用麻烦查了!

嗯?怎么可能?

如果文件在同一个驱动器上,则移动操作是原子操作!该操作实际上是重命名,从前一个目录条目中删除,并将其插入到下一个目录中,指向数据实际所在的相同扇区(或其他),而不重写它。文件系统的内部锁定机制必须在此过程中锁定和阻止目录读取,以防止目录扫描返回损坏的结果。

这意味着,当它出现在目录中时,它不会被锁定;实际上,自从将文件写入上一个目录的关闭操作之后,该文件就不会被打开/修改。

警告- (1) 绝对不能在作为子目录安装的驱动器、分区或其他媒体之间工作。操作系统在幕后进行复制+删除,而不是目录条目编辑。(2) 这种行为是惯例,不是规则。尽管我从未见过它,但文件系统可以随意破坏它,甚至可以不一致地破坏它!

所以这可能会奏效。如果没有,我建议您使用您自己的临时扩展想法(我之前已经为此确切目的做过,但在只能通过共享驱动器通信的客户端和服务器之间进行通信),事实并非如此努力工作,完美无瑕。

如果您自己的想法技术含量太低,并且您在同一台机器上(听起来像),您可以设置一个互斥锁(google that),嵌入文件名,在写入文件时存在,在写入程序;然后在打开从另一个进程读取的每个文件时对其进行阻塞测试。如果您希望第二个进程尽快响应,请将其与文件系统观察程序结合起来。然后为自己花费十倍的精力作为临时文件名的想法而拍拍自己,没有额外的收获>:-}

祝你好运!

于 2013-02-26T15:17:56.387 回答