簡體   English   中英

如何在文件夾創建一次后將文件復制到新文件夾?

[英]How to copy a file to a new folder after folder creation only once?

private void OnCreated(object sender, FileSystemEventArgs e)
        {
            this.Invoke(new Action(
delegate ()
{
    RichTextBoxExtensions.AppendText(richTextBox1, $"Created: {e.FullPath}", Color.GreenYellow);
    RichTextBoxExtensions.AppendText(richTextBox1, $" On: {DateTime.Now}", Color.Yellow);
    richTextBox1.AppendText(Environment.NewLine);

    string folderName = savedGamesPath + "\\Save Game " + DateTime.Now.ToString("dddd, dd MMMM yyyy");
    if (!Directory.Exists(folderName))
    {
        Directory.CreateDirectory(folderName);
    }
    string destFile = Path.Combine(folderName, e.Name);


    File.Copy(e.FullPath, destFile);
}));
        }

我正在使用 filesystemwatcher,問題是它第一次執行 File.Copy 很好,但隨后又執行了一次,第二次出現異常,即找不到目錄。

首先,為什么它連續做兩次? 以及如何使它只復制一次文件?

我為復制您的問題而制作的測試代碼表明,第二個OnCreate事件是在創建Save Game目錄時發生的。 AFAIK 最簡單的檢測方法是首先將其作為DirectoryInfo進行嘗試:

private void onCreated(object sender, FileSystemEventArgs e)
{
    if (Directory.Exists(e.FullPath))
    {
        var fiCopy = new FileInfo(e.FullPath);
        richTextBox1.AppendText($"Created Directory: {e.FullPath}", Color.LightCoral, newLine: false);
        richTextBox1.AppendText($" On: {fiCopy.CreationTime}", Color.Yellow);
        return; // this is a directory, not a file.
    }
    Debug.Assert(string.Equals(Path.GetDirectoryName(e.FullPath), savedGamesPath), "Expecting none other");

    var fiSrce = new FileInfo(e.FullPath);

    string folderName = Path.Combine(
        savedGamesPath,
        $"Save Game {fiSrce.CreationTime.ToString("dddd, dd MMMM yyyy")}");
    // Harmless if already exists
    Directory.CreateDirectory(folderName);

    string destFile = Path.Combine(folderName, e.Name);

    File.Copy(e.FullPath, destFile);
    Debug.Assert(
        fiSrce.CreationTime.Equals(fiSrce.LastWriteTime),
        "Expecting matching CreationTime"
    );

    var fiDest = new FileInfo(destFile);
    Debug.Assert(
        !fiSrce.CreationTime.Equals(fiDest.CreationTime),
        "Expecting different CreationTime"
    );
    fiDest.CreationTime = fiSrce.CreationTime;
    fiDest.LastWriteTime = fiSrce.LastWriteTime;
    Debug.Assert(
        fiSrce.CreationTime.Equals(fiDest.CreationTime),
        "Expecting matching CreationTime"
    );

    richTextBox1.AppendText($"Created: {e.FullPath}", Color.GreenYellow, newLine: false);
    richTextBox1.AppendText($" On: {fiSrce.CreationTime}", Color.Yellow);
}

如果在NET Core 6中構建,只要將 FSW 的SynchronizingObject屬性設置為this ,就不需要Invoke 在舊版 NET Core 3.1 中,可能需要InvokeBeginInvoke無論如何。

提到了 CreationTime 屬性,所以我繼續制作原件和副本的時間匹配。 然而,這些時間似乎並沒有在你所描述的行為中發揮作用。


嘲笑

以您現在的方式,您的保存游戲目錄僅基於日歷日,並且它只會創建一次,即使是像這樣使用游戲 1、2 和 3 測試運行的新游戲也將創建一次。

截屏

在此示例中, FileSystemWatcherMainForm CTor 中初始化。 Net Core 6中,如果SynchronizingObject屬性設置this ,則在事件處理程序中調用RichTextBox時不需要使用Invoke 這種方法似乎不適用於 VS 2019 中的舊版 .NET Core 3.1。可能仍然需要明智地使用 Invoke,或者最好是 BeginInvoke。

public MainForm()
{
    InitializeComponent();
    savedGamesPath = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
        "StackOverflow",
        "filewatcher_with_copy"
    );
    // Start with clean slate for test
    Directory.Delete(savedGamesPath, recursive: true);
    // ===============================

    Directory.CreateDirectory(savedGamesPath);
    _fileSystemWatcher = new FileSystemWatcher()
    {
        Path = savedGamesPath,
        IncludeSubdirectories = false,
        SynchronizingObject = this, // But it seems to complain if not Invoked "anyway"
    };
    _fileSystemWatcher.Created += onCreated;
    _fileSystemWatcher.Changed += onChanged;
    _fileSystemWatcher.Deleted += onDeleted;
    _fileSystemWatcher.EnableRaisingEvents = true;
}
private FileSystemWatcher _fileSystemWatcher;
private readonly string savedGamesPath;
private int _gameCount = 0;
private void buttonNewGame_Click(object sender, EventArgs e)
{
    _gameCount++;
    var gamePrimary = Path.Combine(savedGamesPath, $"Game{_gameCount}.game");
    File.WriteAllText(gamePrimary, String.Empty);
}

附加文本擴展

static class Extensions
{
    public static void AppendText(this RichTextBox richTextBox, string text, Color color, bool newLine = true)
    {
        var colorB4 = richTextBox.SelectionColor;
        richTextBox.SelectionColor = color;
        richTextBox.AppendText(text);
        richTextBox.SelectionColor = colorB4;
        if (newLine) richTextBox.AppendText(Environment.NewLine);
    }
}

NET Core 6 的克隆

NET Core 3.1 的克隆

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM