将 Filesystemwacther 中的所有文件放入虚拟模式 ListView

Jiale Xue - MSFT 46,466 信誉分 Microsoft 供应商
2024-06-12T06:52:55.43+00:00

大家好

我试图做的是;

如何将所有使用filesystemwacther的文件放入虚拟模式ListView.Ythis代码中有一个类和代码Form.Somebody可以显示。

类;

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Permissions;
using static System.IO.Path;

namespace Learning_13
{
    public class FileOperations : FileSystemWatcher
    {
        /// <summary>
        /// Path to check for new files
        /// </summary>
        public string MonitorPath { get; set; }
        /// <summary>
        /// Path to move file(s) too
        /// </summary>
        public string TargetPath { get; set; }

        public FileOperations(string monitorPath, string targetPath, string extension)
        {
            MonitorPath = monitorPath;
            TargetPath = targetPath;

            Created += OnCreated;
            Error += OnError;

            Path = MonitorPath;
            Filter = extension;

            EnableRaisingEvents = true;

            NotifyFilter = NotifyFilters.Attributes
                           | NotifyFilters.CreationTime
                           | NotifyFilters.DirectoryName
                           | NotifyFilters.FileName
                           | NotifyFilters.LastAccess
                           | NotifyFilters.LastWrite
                           | NotifyFilters.Security
                           | NotifyFilters.Size;
        }

        private void OnCreated(object sender, FileSystemEventArgs e)
        {

            try
            {


                System.IO.StreamWriter fileV = new System.IO.StreamWriter(MonitorPath);
                foreach (var sfile in MonitorPath)
                {
                    fileV.WriteLine(sfile);
                }

                var targetFile = Combine(TargetPath, GetFileName(e.FullPath));
                if (File.Exists(targetFile))
                {
                    File.Delete(targetFile);
                }

                File.Move(e.FullPath, targetFile);
            }
            catch (Exception exception)
            {
                Debug.WriteLine(exception.Message);
            }
        }

        public void Start()
        {
            EnableRaisingEvents = true;
        }

        public void Stop()
        {
            EnableRaisingEvents = false;
        }

        private static void OnError(object sender, ErrorEventArgs e) => DisplayException(e.GetException());
        /// <summary>
        /// For debug purposes
        /// For a production environment write to a log file
        /// </summary>
        /// <param name="ex"></param>
        private static void DisplayException(Exception ex)
        {
            if (ex != null)
            {
                Debug.WriteLine($"Message: {ex.Message}");
                Debug.WriteLine("Stacktrace:");
                Debug.WriteLine(ex.StackTrace);
                Debug.WriteLine("");

                DisplayException(ex.InnerException);
            }
        }
    }
}
  1. 使用系统的表格代码;
Form Code using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms; namespace Learning_13
{
public partial class Form1 : Form
{
    List<string> filesAdded = new List<string>();

    private readonly FileOperations _fileOperations =
         new FileOperations(@"C:\", @"D:\Keeper\", "*.txt");
    public Form1()
    {
        InitializeComponent();
        Closing += OnClosing;
    }

    private void OnClosing(object sender, CancelEventArgs e)
    {
        _fileOperations.Stop();
    }

    void listView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
    {
        var item = new ListViewItem();
        if (_fileOperations.MonitorPath.Count() > 0)
        {
            item.Text = _fileOperations.MonitorPath[e.ItemIndex].ToString();
        }
        e.Item = item;

    }

    private void Start_Click(object sender, EventArgs e)
    {
        _fileOperations.Start();
        listView1.VirtualListSize = _fileOperations.MonitorPath.Count();

    }

    private void Stop_Click(object sender, EventArgs e)
    {
        _fileOperations.Stop();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
        listView1.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(listView1_RetrieveVirtualItem);
        listView1.VirtualMode = true;
        listView1.View = View.Details;
        listView1.GridLines = true;
        listView1.Columns.Add("Filename", 600);

        listView1.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(listView1_RetrieveVirtualItem);

    }
}

}

...谢谢。

Note:此问题总结整理于: Put all files from Filesystemwacther to virtual Mode ListView

C#
C#
一种面向对象的类型安全的编程语言,它起源于 C 语言系列,包括对面向组件的编程的支持。
188 个问题
0 个注释 无注释
{count} 票

1 个答案

排序依据: 非常有帮助
  1. Hui Liu-MSFT 48,571 信誉分 Microsoft 供应商
    2024-06-12T08:05:49.42+00:00

    我没有完全使用你的代码,而是自己重写了一段代码。此代码和您的代码之间有两个主要区别。

    我没有自定义 FileOperations 来继承 FileSystemWatcher,而是直接使用 FileSystemWatche,因为我并不真正了解某些方法在 FileOperations 中的作用。

    使用 Created 事件时,文件在创建后立即移动到目标路径,我们没有时间重命名它。这会导致所有文件都使用默认名称,并且代码将删除名称已存在的文件,因此目标路径中将始终只有一个具有默认名称的文件。

    public partial class Form1 : Form  
    {  
        private string TargetPath = @"d:\test11\";  
        private bool IsNewFile = false;  
        private List<ListViewItem> myCache = new List<ListViewItem>();  
        public Form1()  
        {  
            InitializeComponent();  
        }  
    
        private void Form1_Load(object sender, EventArgs e)  
        {  
            listView1.View = View.Details;  
            listView1.GridLines = true;  
            listView1.VirtualMode = true;  
            listView1.RetrieveVirtualItem += ListView1_RetrieveVirtualItem;  
            listView1.Columns.Add("Filename", 600);  
            var watcher = new FileSystemWatcher(@"d:\test");  
    
            watcher.NotifyFilter = NotifyFilters.Attributes  
                                 | NotifyFilters.CreationTime  
                                 | NotifyFilters.DirectoryName  
                                 | NotifyFilters.FileName  
                                 | NotifyFilters.LastAccess  
                                 | NotifyFilters.LastWrite  
                                 | NotifyFilters.Security  
                                 | NotifyFilters.Size;  
            watcher.Created += OnCreated;  
            watcher.Renamed += OnRenamed;  
            watcher.Filter = "*.txt";  
            watcher.IncludeSubdirectories = true;  
            watcher.EnableRaisingEvents = true;  
        }  
    
        private void ListView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)  
        {  
            if (myCache .Count>0)  
            {  
                e.Item = myCache[e.ItemIndex];  
            }  
        }  
    
        private void OnCreated(object sender, FileSystemEventArgs e)  
        {  
            IsNewFile = true;  
        }  
       private void OnRenamed(object sender, RenamedEventArgs e)  
        {  
            if (IsNewFile)  
            {  
                string TargetFile = Path.Combine(TargetPath, e.Name);  
    
                using (StreamWriter fileV = new System.IO.StreamWriter(e.FullPath))  
                {  
                    foreach (var sfile in e.FullPath)  
                    {  
                        fileV.WriteLine(sfile);  
                    }  
                }  
                if (File.Exists(TargetFile))  
                {  
                    File.Delete(TargetFile);  
                }  
              
                //The File.Delete process may not end in time, causing File.Move to be abnormal, indicating that the file is being used.                   
                Thread.S*leep(100);  
                File.Move(e.FullPath, TargetFile);  
                myCache.Add(new ListViewItem() { Text = TargetFile });  
                this.Invoke((MethodInvoker)delegate ()  
                {  
                    listView1.VirtualListSize = myCache.Count;  
                });  
            }  
        }  
    

    更新:

    我构建了一个新的 winform 应用程序,然后从工具箱中添加一个列表视图。

    我对代码做了一个小的修改,因为当被监控的文件夹是 c 的根目录时,实际上在其子目录中创建的新文件也会被监控。

    前面的代码在处理这种情况时会出错。我在 OnRenamed 处理程序中稍微修改了它:

                    FileInfo fileInfo = new FileInfo(e.FullPath);  
                    string TargetFile = Path.Combine(TargetPath, fileInfo.Name);  
    

    目前情况如下:

    87294-1.gif

    异常消息中提到的文件显然不是我们需要监控的 *.txt 文件。它是 Sql Server 的文件,包含 Microsoft SQL Server 关系数据库的事务日志,这些日志记录了自上次检查点以来所有已完成和挂起的事务。

    我不确定为什么会检测到它,但是当我重新检查程序时,我发现了一个我以前没有注意到的问题。

    如果我们创建一个文件但不重命名它,然后重命名前一个文件,则将写入和移动前一个文件。

    我添加了一个新字段并像这样使用它:

            private string newFilePath;  
            private void OnCreated(object sender, FileSystemEventArgs e)  
            {  
                newFilePath = e.FullPath;  
                IsNewFile = true;  
            }  
            private void OnRenamed(object sender, RenamedEventArgs e)  
            {  
                if (IsNewFile && e.OldFullPath == newFilePath)  
               // ......  
    

    如果回复有帮助,请点击“接受答案”并点赞。 注意:如果您想接收此线程的相关电子邮件通知,请按照我们文档中的步骤启用电子邮件通知。

    0 个注释 无注释

你的答案

问题作者可以将答案标记为“接受的答案”,这有助于用户了解已解决作者问题的答案。