问题描述
目前我尽量提高两个窗口服务(C#)设计。服务A产生数据输出(CSV文件),并将其写入到一个临时目录。因此文件被写入到这是一个子迪尔临时目录。主输出目录。然后将文件移动(通过的 File.Move
的)到输出目录(一个成功的写操作之后)。该出口可能被多个线程执行。
另一个服务B试图获取一个定义的时间间隔从这个输出目录中的文件。如何保证的 Directory.GetFiles()
的排除锁定的文件。
-
我应该尝试通过创建一个新的FileStream检查每一个文件(使用(
流流=新的FileStream(MyFilename.txt,FileMode.Open)
)的说明here. -
还是应该在生产性服务业(A)使用临时文件名(* .csv.tmp)是 自动排除由消费者serivce(B)中与适当的搜索pattterns。而此举结束后重命名文件。
- 是否有更好的方法来处理这些文件中列出的操作。
不要打扰检查!
咦?怎么会这样?
如果该文件是相同的驱动器上,移动操作是原子!该操作是一个有效的重命名,删除从previous的目录条目,并将其插入下一个目录,指向相同扇区(或凡是)其中数据真的是,不用重写它。该文件系统的内部锁定机制具有锁定和放大器;在此过程中,以prevent从返回腐败结果的目录扫描块目录中读取。
这意味着,通过它曾经出现在一个目录中的时间,也不会被锁定;事实上,该文件将不会被打开/自认为写于previous目录关闭操作修改。
警告 - (1)绝对不会驱动器,分区或其他媒体之间安装一个子目录工作。操作系统做了拷贝+删除幕后,而不是一个目录条目的编辑。 (2)这种行为是一种惯例,而不是规则。虽然我从来没有见过它,文件系统可以自由地打破它,甚至不一致打破它!
因此,这可能会工作。如果不是这样,我推荐使用温度扩展自己的想法(我之前已经做了这个确切的目的,但在客户端和服务器只能由通过共享驱动器通信通话之间),这并不是说硬并准确无误地运行。
如果你自己的想法太科技含量低,和你在同一台机器上(听起来像你),你可以设置一个互斥量(谷歌的),嵌入式文件名,即生活,同时该文件是为写,在写进程;然后做一个阻塞测试就可以了,当你打开你从其他进程读取每个文件。如果你想在第二个进程作出回应尽快结合这与文件系统守望。然后拍拍自己的背的花十倍的努力,为临时文件名的想法,没有额外的增益> - }
祝你好运!
Currently I try to improve the design of two windows services (C#).Service A produces data exports (csv files) and writes them to a temporary directory.So the file is written to a temporary directory that is a sub dir. of the main output directory.Then the file is moved (via File.Move
) to the output directory (after a successful write).This export may be performed by multiple threads.
Another service B tries to fetch the files from this output directory in a defined interval.How to assure that Directory.GetFiles()
excludes locked files.
Should I try to check every file by creating a new FileStream (using(
Stream stream = new FileStream("MyFilename.txt", FileMode.Open)
) asdescribedhere.Or should the producer service (A) use temporary file names (*.csv.tmp) that are automatically excluded by the consumer serivce (B) with appropriate search pattterns. And rename a file after the move was finished.
- Are there better ways to handle such file listing operations.
Don't bother checking!
Huh? How can that be?
If the files are on the same drive, a Move operation is atomic! The operation is effectively a rename, erasing the directory entry from the previous, and inserting it into the next directory, pointing to the same sectors (or whatevers) where the data really are, without rewriting it. The file system's internal locking mechanism has to lock & block directory reads during this process to prevent a directory scan from returning corrupt results.
That means, by the time it ever shows up in a directory, it won't be locked; in fact, the file won't have been opened/modified since the close operation that wrote it to the previous directory.
caveats - (1) definitely won't work between drives, partitions, or other media mounted as a subdirectory. The OS does a copy+delete behind the scenes instead of a directory entry edit. (2) this behaviour is a convention, not a rule. Though I've never seen it, file systems are free to break it, and even to break it inconsistently!
So this will probably work. If it doesn't, I'd recommend using your own idea of temp extensions (I've done it before for this exact purpose, but between a client and server that only could talk by communicating via a shared drive) and it's not that hard and worked flawlessly.
If your own idea is too low-tech, and you're on the same machine (sounds like you are), you can set a mutex (google that), with the filename embedded, that lives while the file is being written, in the writer process; then do a blocking test on it when you open each file you are reading from the other process. If you want the second process to respond ASAP combine this with the filesystem watcher. Then pat yourself on the back for spending ten times the effort as the temp filename idea, with no extra gain >:-}
good luck!
这篇关于使用Directory.GetFiles()或EnumerateFiles与包含锁定文件的目标目录最佳实践?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!