繁体   English   中英

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

[英]How can I watch for newly created files and wait for them to be unlocked?

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

第二个问题,我该如何使用所有这些方法,这两种方法以及更改的事件(下面的代码)? 单击按钮时会发生按钮单击事件,它将创建新的jpg文件。 然后在按钮单击事件中,我想开始观看它,并在标签上显示一条消息,例如:“正在创建文件等待”,然后在创建文件并准备使用时创建“文件已创建”。

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); }
        }

在watch方法中:

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文件则是IMG_0001.JPG

但是我不确定这是否就是为什么要去参加比赛,然后再做一次比赛。

我还检查了e.FullPath中的文件始终为.jpg而不是cr2。 问题是,为什么它到达那里再一次,我如何确保文件真的准备好了? (“文件就绪”)

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

我发现您使用观察器的方式存在一些问题。

  • CameraHandler.TakePhoto应在调用CameraHandler.TakePhoto之前运行,否则您将有机会错过。
  • 不要在每个TakePhotoButton_Click上创建监视程序的新实例,也不要停止旧的实例。 否则,您每次点击都会获得一个新的正在运行的监视程序,并与您拥有的监视程序一样多地调用watcher_Changed
  • 我读过有一个机会可以观察者被垃圾收集。 我不确定这是否属实,但请确保安全并将其保存到本地。

您现在正在等待的是写一些.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
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM