Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Directory.GetFiles()或枚举包含锁定文件的目标目录的文件的最佳实践?_C#_Filesystems_.net - Fatal编程技术网

C# 使用Directory.GetFiles()或枚举包含锁定文件的目标目录的文件的最佳实践?

C# 使用Directory.GetFiles()或枚举包含锁定文件的目标目录的文件的最佳实践?,c#,filesystems,.net,C#,Filesystems,.net,目前,我试图改进两个windows服务(C#)的设计。 服务A生成数据导出(csv文件)并将其写入临时目录。 因此,该文件被写入一个临时目录,该目录是一个子目录。主输出目录的。 然后文件被移动(通过file.Move)到输出目录(成功写入后)。 此导出可以由多个线程执行 另一个服务B尝试在定义的时间间隔内从此输出目录获取文件。 如何确保Directory.GetFiles()排除锁定的文件 我应该通过创建一个新的文件流(使用 (Stream=newfilestream(“MyFilename.t

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

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

  • 我应该通过创建一个新的文件流(使用 (
    Stream=newfilestream(“MyFilename.txt”,FileMode.Open)
    )作为 描述

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

  • 是否有更好的方法来处理此类文件列表操作

  • 一种方法是在文件使用时从writing应用程序中将其标记为临时文件,并且仅在文件写入并关闭后才取消标记,例如

    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.
    }
    
    别费心检查了! 啊?怎么会这样

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

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

    注意事项-(1)在驱动器、分区或作为子目录装入的其他媒体之间肯定不起作用。操作系统在后台执行复制+删除操作,而不是目录条目编辑。(2)这种行为是一种惯例,而不是规则。尽管我从未见过它,但文件系统可以随意破坏它,甚至可以不一致地破坏它

    因此,这可能会奏效。如果不行,我建议您使用自己的临时扩展(我以前也这样做过,但在客户端和服务器之间,只能通过共享驱动器进行通信),这样做并没有那么困难,而且工作得完美无缺

    如果你自己的想法技术含量太低,并且你在同一台机器上(听起来像是),你可以设置一个互斥(谷歌),嵌入文件名,在文件写入过程中,文件名在写入进程中存在;然后在打开从另一个进程读取的每个文件时,对文件名进行阻塞测试。如果希望第二个进程尽快响应,请将此与文件系统监视程序结合起来。然后拍拍自己的背,因为它花费了与e temp文件名idea,无额外增益>:-}


    祝你好运!

    为什么不在输出目录上使用
    FileSystemWatcher
    ?这样,当文件放在那里时,服务B会立即得到通知,而不必担心扫描.RE FileSystemWatcher-如果在创建文件时而不是关闭文件时触发,它实际上可能比定期轮询更糟糕,如“B”w当文件被锁定时,您很可能会跟踪它。文件可能会在第1行之后但在第3行之前被“B”击中。此外,当通过File.move写入文件时,这种类型的控件是不可能的。注意到了。我想您可以在B监视器所在的不同目录中创建该文件,并在移动它之前将其设置为临时-然后在在移动完成后向您致敬。确实如此。移动可能会保留属性(希望是原子的)。是的,我决定使用临时文件扩展名。到目前为止效果非常好。感谢讨论此主题。