C# 如何等到 File.Exists?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14816425/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to wait until File.Exists?
提问by user1750355
I have an app, listening for the *.log file in a chosen folder. I used FileSystemWatcher
.
我有一个应用程序,在选定的文件夹中侦听 *.log 文件。我用过FileSystemWatcher
。
But there is a problem. The other app responsible for making that file takes following steps:
但有一个问题。负责制作该文件的另一个应用程序执行以下步骤:
- Make a *.gz file
- Unpack it to txt file (some random file name)
- Change the *.txt name to proper one with *.log extension.
- 制作一个 *.gz 文件
- 解压到txt文件(一些随机文件名)
- 将 *.txt 名称更改为带有 *.log 扩展名的正确名称。
And I can not change this behaviour.
我无法改变这种行为。
So I made 2 FileSystemWatcher
s for *.gz, and *.txt files. Why? Because this app sometimes doesn't unpack the gz file, and sometimes doesn't rename the txt file to the final *.log file.
所以我FileSystemWatcher
为 *.gz 和 *.txt 文件制作了 2秒。为什么?因为这个app有时不解压gz文件,有时也不把txt文件重命名为最终的*.log文件。
FileSystemWatcher2
catches txt file, then (in the most cases it is renamed to log in the next 1000ms) I need to wait some time to check if txt file exists (if not, it seems to be renamed to the final *.log file).
FileSystemWatcher2
捕获 txt 文件,然后(在大多数情况下,它被重命名为在接下来的 1000 毫秒内登录)我需要等待一些时间来检查 txt 文件是否存在(如果不存在,它似乎被重命名为最终的 *.log 文件)。
The question is, how to check if file exists without Thread.Sleep()
to prevent UI freeze?
问题是,如何在不Thread.Sleep()
防止 UI 冻结的情况下检查文件是否存在?
I hope it is clear, if not I will try to describe it better. I think this is a complex problem.
我希望它很清楚,如果不是,我会尝试更好地描述它。我认为这是一个复杂的问题。
Some code sample:
一些代码示例:
Watcher for gz file:
gz 文件的观察者:
private void fileSystemWatcher_Created(object sender, FileSystemEventArgs e)
{
//this is for gz files in case if gz file is not unpacked automatically by other app
//I need to wait and check if gz was unpacked, if not, unpack it by myself,
//then txt watcher will catch that
Thread.Sleep(5000);
if (File.Exists(e.FullPath))
{
try
{
byte[] dataBuffer = new byte[4096];
using (System.IO.Stream fs = new FileStream(e.FullPath,
FileMode.Open,
FileAccess.Read))
{
using (GZipInputStream gzipStream = new GZipInputStream(fs))
{
string fnOut = Path.Combine(path_to_watcher,
Path.GetFileNameWithoutExtension(e.FullPath));
using (FileStream fsOut = File.Create(fnOut))
{
StreamUtils.Copy(gzipStream, fsOut, dataBuffer);
}
}
}
}
catch { //Ignore }
}
}
Watcher for txt file:
txt文件的观察者:
private void fileSystemWatcher2_Created(object sender, FileSystemEventArgs e)
{
//this is for txt file
Thread.Sleep(3500);
if (File.Exists(e.FullPath))
{
//make my actions
}
else
{
//make my actions
}
}
回答by LukeHennerley
You can use sleep without locking the UI thread, you essentially sleep a seperate thread.
您可以在不锁定 UI 线程的情况下使用 sleep,您实际上是在睡眠一个单独的线程。
public event EventHandler FileCreated;
public void CheckFileExists()
{
while(!File.Exists(""))
{
Thread.Sleep(1000);
}
FileCreated(this, new EventArgs());
}
Then call this as:
然后将其称为:
Thread t = new Thread(CheckFileExists);
this.FileCreated += new EventHandler(somemethod);
t.Start();
public void SomeMethod(object sender, EventArgs e)
{
MessageBox.Show("File Created!");
}
Or as mentioned in another post use a BackGroundWorker
in place of the seperate thread, put the code I mentioned into DoWork
and listen for OnFinish
event but seeing as there isn't that much work to do either methods are fine.
或者如另一篇文章中所述,使用 aBackGroundWorker
代替单独的线程,将我提到的代码放入DoWork
并侦听OnFinish
事件,但由于没有太多工作要做,这两种方法都很好。
回答by Dave Bish
You can use a BackGroundWorkerto monitor the file system - and avoid freezing your UI
您可以使用BackGroundWorker来监视文件系统 - 并避免冻结您的 UI
回答by Boppity Bop
Actually FileSystemWatcher Created event called in separate thread by .NET itself.. So basically you need to do absolutely nothing. Your code is OK as it is.
实际上 FileSystemWatcher Created 事件由 .NET 本身在单独的线程中调用。所以基本上你不需要做任何事情。您的代码没有问题。
Here is the proof:
这是证据:
class Program
{
static void Main(string[] args)
{
FileSystemWatcher fw = new FileSystemWatcher(@"C:\temp");
fw.Created += fileSystemWatcher_Created;
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
fw.EnableRaisingEvents = true;
Console.ReadLine();
}
static void fileSystemWatcher_Created(object sender, FileSystemEventArgs e)
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
}
}
回答by Tamir Reiss
int i = 0;
while (!File.Exists && i < 30) //limit the time to whait to 30 sec
{
Threed.Sleep(1000);
File.Refresh();
i++;
}