一个应用程序就是filewatcher,它一直在后台运行。它会在添加任何新文件时更新数据库。此应用程序仅更新数据库的两个字段。主键部分和**附件。 ** 同样,我有一个不同的主要应用程序,由不同PC中的不同用户处理。因此,当数据库中的任何新文件更新时,此应用程序有一个传输按钮。此按钮的操作使文件从单元格[2]移动到单元格[3]。这意味着它将所有文件从位置C:\ user \ fab移动到位置:C:\ user \ release。此应用程序没有任何文件监视器
所以我的问题是:
文件观察程序正在更新数据库的所有内容。但是当其他用户在单个**转移按钮的帮助下移动文件时按**。在另一台PC上运行的文件观察程序认为该文件已被删除,并且它接受删除数据库的命令。任何解决方案。请帮帮我。
链接第一部分:https://imageshack.com/i/idZuIKPnj
第二部分:https://imageshack.com/i/idJzeEtwj
代码段:
private void OnChanged(object source, FileSystemEventArgs e)
{
switch (e.ChangeType)
{
case WatcherChangeTypes.Created:
//Insert file in database
this.Invoke(addItemInList, "File: " + e.FullPath + " Created");
{
string filename = Path.GetFileName(e.FullPath);
filename = filename.Substring(0, filename.LastIndexOf("."));
SqlConnection con = new SqlConnection(@"Data Source=DVSQL\SQLEXPRESS;Initial Catalog=CncDB;User ID=CncDbUser;password=gcodedata");
con.Open();
SqlCommand cmd = new SqlCommand(@"INSERT INTO cncinfo (part,draftpath) VALUES ('" + filename + "','" + e.FullPath + "') ", con);
cmd.ExecuteNonQuery();
con.Close();
}
break;
case WatcherChangeTypes.Deleted:
//remove file from database
this.Invoke(addItemInList, "File: " + e.FullPath + " Deleted");
{
string filename = Path.GetFileName(e.FullPath);
filename = filename.Substring(0, filename.LastIndexOf("."));
SqlConnection con = new SqlConnection(@"Data Source=DVSQL\SQLEXPRESS;Initial Catalog=CncDB;User ID=CncDbUser;password=gcodedata");
con.Open();
SqlCommand cmd = new SqlCommand(@"delete cncinfo where part='" + filename + "' ;", con);
cmd.ExecuteNonQuery();
con.Close();
}
break;
case WatcherChangeTypes.Changed:
///if you are storing file in database(not file name whole file in binary format)
///then you can update the file in database here
///this event will be fired when any data has changed in the file.
this.Invoke(addItemInList, "File: " + e.FullPath + " Changed");
{
string filename = Path.GetFileName(e.FullPath);
filename = filename.Substring(0, filename.LastIndexOf("."));
SqlConnection con = new SqlConnection(@"Data Source=DVSQL\SQLEXPRESS;Initial Catalog=CncDB;User ID=CncDbUser;password=gcodedata");
con.Open();
SqlCommand cmd = new SqlCommand(@"update cncinfo set part='" + filename
+ "',draftpath='" + e.FullPath + "' where part='" + filename + "'", con);
cmd.ExecuteNonQuery();
con.Close();
this.Validate();
}
break;
}
}
private void OnRenamed(object source, RenamedEventArgs e)
{
//Update then old filename with new here
this.Invoke(addItemInList, string.Format("File: {0} renamed to {1}", e.OldFullPath, e.FullPath));
{
//string extension = e.FullPath.Substring(e.FullPath.LastIndexOf("."));
string oldFileName = Path.GetFileName(e.OldFullPath);
oldFileName = oldFileName.Substring(0, oldFileName.LastIndexOf("."));
string filename = Path.GetFileName(e.FullPath);
filename = filename.Substring(0, filename.LastIndexOf("."));
SqlConnection con = new SqlConnection(@"Data Source=DVSQL\SQLEXPRESS;Initial Catalog=CncDB;User ID=CncDbUser;password=gcodedata");
con.Open();
SqlCommand cmd = new SqlCommand(@"update cncinfo set part='" + filename + "',draftpath='" + e.FullPath + "' where part='" + oldFileName + "'", con);
cmd.ExecuteNonQuery();
con.Close();
this.Validate();
}
}
答案 0 :(得分:0)
你的文件观察者只有3个动作。您的文件观察者是否以某种方式加载文件夹的历史记录?换句话说,如果文件观察程序不保留历史数据,则可以终止Filewatcher.exe,移动文件,然后重新启用。这种方法的问题是当exe关闭时你可能会错过文件夹中的更改或创建。
第二个解决方案是复制文件并将附加“FILEMOVED202”的原始文件或任何唯一字符串重命名到文件名的末尾,这样Test.doc将是TestFILEMOVED202.doc并将触发您的更改功能文件观察者。在更改的函数中,您可以将函数字符串的文件名字符串。如果它存在于更改函数中,则从文件观察器中删除实际文件,使用另一个标志禁止删除日志记录,并使用移动的值或其他任何内容更新数据库。
您在文件观察程序中唯一可以访问的是文件名,而不是文件内容,因此我会将其用作您的标记工具。
答案 1 :(得分:0)
转到第二个按下“传输”按钮的应用程序。使该代码将文件复制到传输目标,而不是移动它,以便删除函数永远不会触发。在文件副本重命名原始文件之后,将任何唯一字符串添加到文件名。像Test.docx一样会成为TestFileMovedTrans.doc。然后,这将触发您文件观察者的更改事件,它将进入上面的更改代码。在该更改代码中,检查唯一字符串“FileMovedTrans”的文件名或其他内容。如果它具有该字符串,则移动功能导致它&您可以记录并删除文件
删除更改代码中的文件后,将再次触发Filewatcher删除代码,您将再次检查文件名中的字符串。如果字符串存在,则不将其作为已删除状态记录到数据库,因为它仅被移动,如果字符串不在文件名中,则只使用常规的Delete功能。
答案 2 :(得分:0)
您还应该为移动文件的目标文件夹声明另一个filewatcher。但是,正如我告诉你你的ASP.NET室你必须签署该特定文件(即文件大小,修改日期和文件类型的组合)你可以创建一个类FileSignature
public class FileSignature
{
public int FileSize { get; set; }
public DateTime ModifiedDate { get; set; } //We could not take CreatedDate because it will be changed once the file moved but, modified date only change when it modified by editor (ie. notepad)
public String FileType { get; set; }
public String OldFileName { get; set; } //this is not the part of the combination of signature. It is just to get the old file name which is moved from.
}
并在发生删除文件事件时将该类的对象创建到列表中。
private List<FileSignature> movedList = new List<FileSignature>();
private void Watcher1_OnChange()
{
....
case Delete:
FileSignature singature = new FileSignature();
FileInfo info = new System.IO.FileInfo(e.FullPath);
signature.FileSize = info.Length;
signature.ModifiedDate = info.LastWriteTime;
singature.FileType = info.Extension;
signature.OldFileName = e.FullPath;
movedList.Add(signature);
break;
}
FileInfo类将包含有关该文件的所有信息。
现在,您需要另一个FileWatcher
对象作为目标文件夹路径(即C:\ user \ release)。
在第二个文件观察者OnChanged
事件中,您将获得该文件已创建并从其他位置移动的事件。
private void Watcher2_OnChange()
{
....
case Created:
FileInfo info = new FileInfo(e.FullPath);
FileSignature[] found = (from FileSignature sign in movedList
where sign.ModifiedDate == info.LastWriteTime &&
sign.FileType == info.Extension &&
sign.FileSize == info.Length
select sign).ToArray()
if (found.Length > 0) //if the file found then it will be known as moved file otherwise created.
{
FileSignature signature = found[0]; //we will take only one file from the index 0. coz the file watcher event will occur for every file separately.
//remove that file from the list first. So, further undeleted item in the list will be known as deleted at the end.
movedList.Remove(signature);
string oldFileName = signature.OldFileName; //this will contain full path of file which has been moved to new location.
string newFileName = e.FullPath; //this will return new file name which is moved from source directory
//Now you can perform you database update process here for move file.
//you have both path and flag that file is moved.
}
else
{
//Now you can perform you database update process here for create file.
}
break;
}
现在,代码的主要部分在这里
现在您需要一个标志,当整个过程完成(文件移动)时,该标志将从主应用程序更新。您可以使用其他FileWatcher
。
当你从主应用程序获得进程已经定义的标志时,你可以调用另一种方法从数据库中删除movedList
中存在的项目。
private void DeleteItems()
{
foreach (FileSignature signature in movedList)
{
string filename = signature.OldFileName
//Delete from the database. coz this files are known as deleted but not moved to destination
}
}