如何查看新创建的文件并等待它们解锁?

时间:2015-12-13 15:55:35

标签: c# .net winforms

首先是手表方法;我需要注意任何新创建的jpg文件,因为我还不知道文件名。我的程序每次在TextBox指定的目录中创建一个新的jpg。所以我的第一个问题是如何在创建文件时知道/获取文件名?

第二个问题,我怎样才能使用所有这些方法,这两个方法和事件发生了变化(下面的代码)?当我点击它时,我有一个按钮点击事件,它将创建新的jpg文件。然后在按钮单击事件中,我想开始观看它,并在标签上给出一条消息:"创建文件等待",然后创建文件并准备好使用"文件创建&# 34。

private void watch()
{
    FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.Path = SavePathTextBox.Text;
    watcher.NotifyFilter = NotifyFilters.LastWrite;
    watcher.Filter = "*.jpg";
    watcher.Changed += watcher_Changed;
    watcher.EnableRaisingEvents = true;
}

然后事件watcher_Changed

void watcher_Changed(object sender, FileSystemEventArgs e)
{

}

检查文件是否被锁定的方法

public static bool IsFileReady(String sFilename)
{
    // If the file can be opened for exclusive access it means that the file
    // is no longer locked by another process.
    try
    {
        using (FileStream inputStream = File.Open(sFilename, FileMode.Open, FileAccess.Read, FileShare.None))
        {
            if (inputStream.Length > 0)
            {
                return true;
            }
            else
            {
                return false;
            }

        }
    }
    catch (Exception)
    {
        return false;
    }
}

这是我试过的:

在按钮点击事件中:

private void TakePhotoButton_Click(object sender, EventArgs e)
        {
            try
            {
                if ((string)TvCoBox.SelectedItem == "Bulb") CameraHandler.TakePhoto((uint)BulbUpDo.Value);
                else CameraHandler.TakePhoto();
                watch();
            }
            catch (Exception ex) { ReportError(ex.Message, false); }
        }

在观察方法中:

private void watch()
        {
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = SavePathTextBox.Text;
            watcher.NotifyFilter = NotifyFilters.LastWrite;
            watcher.Filter = "*.JPG";
            watcher.Changed += watcher_Changed;
            watcher.EnableRaisingEvents = true;
        }

事件watcher_Changed

void watcher_Changed(object sender, FileSystemEventArgs e)
        {
            if (IsFileReady(e.FullPath) == false)
            {
                this.Invoke((Action)delegate { label6.Text = "Busy"; });
            }
            else
            {
                this.Invoke((Action)delegate { label6.Text = "File Ready"; }); 
            }
        }

查找文件是否被锁定的方法:

public static bool IsFileReady(String sFilename)
        {
            // If the file can be opened for exclusive access it means that the file
            // is no longer locked by another process.
            try
            {
                using (FileStream inputStream = File.Open(sFilename, FileMode.Open, FileAccess.Read, FileShare.None))
                {
                    if (inputStream.Length > 0)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }

                }
            }
            catch (Exception)
            {
                return false;
            }
        }

问题在于,在大多数情况下,它有时会进入watcher_Changed事件中的一行:

this.Invoke((Action)delegate { label6.Text = "File Ready"; });

连续两次或连续拍摄3次。 我可以说,每次点击我的相机拍摄一张照片,它就会创建两个文件,例如名称:IMG_0001.CR2和Jpg one:IMG_0001.JPG

但是我不确定这是不是为什么它能够参加比赛并在那里进行一次以上的比赛。

我还检查了e.FullPath中的文件总是.jpg而且从不cr2。 问题是为什么它会更多地到达那里,我怎样才能确保文件真的准备好了? ("文件就绪")

也许我需要以某种方式跟踪文件大小从0kb到大小不再变化然后决定它是否准备就绪?

1 个答案:

答案 0 :(得分:0)

我看到你使用观察者的方式存在一些问题。

  • Watcher应该在您致电CameraHandler.TakePhoto之前运行,或者有一个(小)机会您会错过它。
  • 要么不在每TakePhotoButton_Click创建一个新的观察者实例,要么停止旧实例。否则,每次点击都会得到新的正在运行的观察者,并且尽可能多地给watcher_Changed打电话。{/ li>
  • 我看过有机会观察者可以收集垃圾。我不确定它是否属实,而是安全并将其保存到当地某个领域。

您现在正在等待的是写入某个.jpg文件的结束。这可能会做你需要的,在这种情况下它是好的。但是如果你想等待文件创建,你需要不同的设置。这对我有用:

string watchDir = Application.StartupPath;
watcher = new FileSystemWatcher(watchDir, "*.jpg");
watcher.NotifyFilter |= NotifyFilters.Size;
watcher.Created += new FileSystemEventHandler(watcher_Created);
watcher.EnableRaisingEvents = true;

protected void watcher_Created(object sender, FileSystemEventArgs e)
{
    string changeType = e.ChangeType.ToString();
    if (changeType != "Created")
    {
        return;
    }

    // file is created, wait for IsFileReady or whatever You need
}