我想将目录中创建的所有文件的文件信息插入数据库。如果我在目录中删除少量文件,我的程序将执行此操作,但如果我一次在目录中删除大量文件,则它不会获取所有文件(我没有进行大量测试,但它只插入了大约当我尝试一次将 800 个文件放入目录时,我的数据库中包含了 200 个名称)。
这是我的代码:
static void Main(string[] args)
{
// Create a new FileSystemWatcher and set its properties.
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = @"C:\dropDirectory";
// Add event handlers.
watcher.Created += new FileSystemEventHandler(OnChanged);
// Begin watching.
watcher.EnableRaisingEvents = true;
while(DateTime.Now.Hour < 10);
}
private static void OnChanged(object source, FileSystemEventArgs e)
{
string strInsert = "INSERT INTO Files (Filename) VALUES ('" + e.Name + "')";
string strConnection = "Server = server_name; Database = database_name; User Id = user_id; Password = password;";
using (SqlConnection con = new SqlConnection(strConnection))
{
using (SqlCommand cmd = new SqlCommand(strInsert, con))
{
con.Open();
cmd.ExecuteScalar();
}
}
}
我需要进行哪些更改,以便为目标目录中删除的每个文件调用我的 OnChanged 方法,无论一次删除的文件数量如何?预先感谢。
您的问题是缓冲区大小,以及众所周知且有记录的问题
FileSystemWatcher
使用 ReadDirectoryChangesW
WinApi 调用带有一些相关标志
当您第一次调用
时,系统会分配一个 用于存储变化信息的缓冲区。该缓冲区与 目录句柄直到它关闭并且其大小不会改变 在其生命周期内。调用之间发生的目录更改 该函数被添加到缓冲区,然后与下一个函数一起返回 称呼。 如果缓冲区溢出,则缓冲区的全部内容都会被清空 被丢弃了ReadDirectoryChangesW
FileSystemWatcher
中的类似物是FileSystemWatcher.InternalBufferSize
属性
备注 您可以将缓冲区设置为 4 KB 或更大,但不得 超过 64 KB。如果您尝试将 InternalBufferSize 属性设置为 小于 4096 字节,您的值将被丢弃,并且 InternalBufferSize 属性设置为 4096 字节。为了最好 性能,在基于 Intel 的计算机上使用 4 KB 的倍数。
系统通知组件文件更改,并存储这些更改 组件创建并传递给 API 的缓冲区发生变化。 每个 事件最多可以使用 16 个字节的内存,不包括文件名。 如果短时间内发生很多变化,缓冲区可能会溢出。 这会导致组件失去对目录中更改的跟踪, 并且它只会提供全面通知。增加尺寸 该缓冲区可以防止丢失文件系统更改事件。然而, 增加缓冲区大小是昂贵的,因为它来自非分页 内存无法换出到磁盘,因此请保持缓冲区尽可能小 尽可能。 为了避免缓冲区溢出,请使用 NotifyFilter 和 IncludeSubdirectories 属性可过滤掉不需要的更改 通知。
如果情况变得更糟,您可以结合使用轮询和跟踪,它已经帮助我摆脱了几次麻烦。