1.关于本工具
这个工具是我用WPF写的一个测试工具,需求大致上是:有一个文件,它不定期会发生变化,现在要求监控这个文件,每当该文件改变,则创建一个该文件的副本。
在这个程序中,指定一个被监控文件的路径,设定一个拍摄快照的时间间隔,每次拍摄文件的快照后,根据设定比对当次快照与之前快照中文件的大小或最后修改时间,发生变化则创建副本。副本的文件名是当前的时间(时、分、秒、毫秒),副本的扩展名与被监控的文件一致。
程序启动时可以从config.xml中读取配置:
<?xml version="1.0" encoding="gb2312"?> <Config> <FilePath>test.txt</FilePath> <MonInterval>200</MonInterval> <MonType>1</MonType> </Config>
程序的副本被复制到一个名为copy的文件夹中
config.xml与文件夹copy都在工程目录中,在编译后通过后期生成事件命令行复制到可执行文件所在目录下
xcopy "$(ProjectDir)config\config.xml" "$(TargetDir)" /Y xcopy "$(ProjectDir)copy\test.txt" "$(TargetDir)"\copy\ /Y
2.程序界面
界面布局的xaml文档为:
<Window x:Name="wndwCyclop" x:Class="Cyclop.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Cyclop" Height="329" Width="472" ResizeMode="CanMinimize" WindowStartupLocation="CenterScreen" Loaded="wndwCyclop_Loaded" Icon="Cyclop.ico"> <Grid Margin="0,0,4,-2"> <!--程序标题--> <Label x:Name="lblTitle" Content="Cyclop 文件比对兼副本创建工具" HorizontalAlignment="Left" Margin="42,21,0,0" VerticalAlignment="Top" FontSize="24" FontFamily="YouYuan" FontWeight="Bold"/> <!--被监控文件路径--> <Label x:Name="lblFilePath" Content="被监控文件路径:" HorizontalAlignment="Left" Margin="31,76,0,0" VerticalAlignment="Top" Width="101"/> <TextBox x:Name="txtFilePath" HorizontalAlignment="Left" Height="23" Margin="146,79,0,0" Text="" VerticalAlignment="Top" Width="194"/> <Button x:Name="btnBrowse" Content="..." HorizontalAlignment="Left" Margin="354,80,0,0" VerticalAlignment="Top" Width="75" RenderTransformOrigin="0.747,0.364" Click="btnBrowse_Click"/> <!--快照时间间隔(单位毫秒)--> <Label x:Name="lblInterval" Content="快照时间间隔ms:" HorizontalAlignment="Left" Margin="31,107,0,0" VerticalAlignment="Top" Width="101"/> <TextBox x:Name="txtInterval" HorizontalAlignment="Left" Height="23" Margin="146,110,0,0" Text="" VerticalAlignment="Top" Width="194"/> <!--监控选项--> <RadioButton x:Name="rdbSizeOnly" Content="监控文件大小" HorizontalAlignment="Left" Margin="102,158,0,0" VerticalAlignment="Top" ToolTip="仅监控文件的大小,该项属性改变时创建副本"/> <RadioButton x:Name="rdbTimeOnly" Content="监控最后修改时间" HorizontalAlignment="Left" Margin="249,158,0,0" VerticalAlignment="Top" ToolTip="仅监控文件的最后修改时间,该项属性改变时创建副本"/> <Button x:Name="btnStart" Content="开始监控" HorizontalAlignment="Left" Margin="60,209,0,0" VerticalAlignment="Top" Width="153" Height="48" RenderTransformOrigin="0.5,0.5" Click="btnStart_Click"> <Button.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform AngleX="27.474"/> <RotateTransform/> <TranslateTransform X="-12.48"/> </TransformGroup> </Button.RenderTransform> </Button> <Button x:Name="btnStop" Content="中止监控" HorizontalAlignment="Left" Margin="243,209,0,0" VerticalAlignment="Top" Width="153" Height="48" RenderTransformOrigin="0.5,0.5" IsEnabled="False" Click="btnStop_Click"> <Button.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform AngleX="-27.474"/> <RotateTransform/> <TranslateTransform X="12.48"/> </TransformGroup> </Button.RenderTransform> </Button> </Grid> </Window>
3.程序源码
/* * Cyclop 文件比对兼副本创建工具 * 作者姓名:Tsybius * 创建时间:2014-12-02 */ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; // 代码中需要手动添加的命名空间 using System.IO; using System.Xml; using System.Windows.Threading; // DispatcherTimer要用到它 using Microsoft.Win32; // OpenFileDialog要用到它 namespace Cyclop { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } /// <summary> /// 被监控文件的大小 /// </summary> long lFileSize = -1; /// <summary> /// 被监控文件的最后修改日期 /// </summary> DateTime dtLastWrite = new DateTime(2000, 1, 1, 0, 0, 0); /// <summary> /// 监控文件大小和信息 /// </summary> DispatcherTimer dsptMon = new DispatcherTimer(); /// <summary> /// 加载界面时触发:读取配置 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void wndwCyclop_Loaded(object sender, RoutedEventArgs e) { try { // 初始化控件值 this.txtFilePath.Text = ""; this.txtInterval.Text = "1000"; this.rdbSizeOnly.IsChecked = true; if (!File.Exists("config.xml")) { throw new Exception("没有找到配置文件,程序将启动默认配置"); } // 读取配置文件 XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load("config.xml"); XmlNode nodeRoot = xmlDoc.SelectSingleNode("Config"); XmlNodeList nodeList = nodeRoot.ChildNodes; foreach (XmlNode node in nodeList) { switch (((XmlElement)node).Name) { case "FilePath": { this.txtFilePath.Text = ((XmlElement)node).InnerText; } break; case "MonInterval": { this.txtInterval.Text = ((XmlElement)node).InnerText; } break; case "MonType": { switch (((XmlElement)node).InnerText) { case "1": { this.rdbSizeOnly.IsChecked = true; } break; case "2": { this.rdbTimeOnly.IsChecked = true; } break; default: break; } } break; default: break; } } // 设置定时器内容 dsptMon = new DispatcherTimer(); dsptMon.Interval = new TimeSpan(1000); dsptMon.Tick += (arg, obj) => { FileInfo fi = new FileInfo(txtFilePath.Text); long size = fi.Length; DateTime last = fi.LastWriteTime; //监控文件大小的改变,改变则创建文件副本 if ((bool)rdbSizeOnly.IsChecked) { if (fi.Length != lFileSize) { File.Copy(txtFilePath.Text, "copy/" + DateTime.Now.ToString("HHmmss_fff") + fi.Extension.ToLower()); lFileSize = fi.Length; return; } } //监控文件最后修改时间的改变,改变则创建文件副本 else if ((bool)rdbTimeOnly.IsChecked) { if (fi.LastWriteTime.Year != dtLastWrite.Year || fi.LastWriteTime.Month != dtLastWrite.Month || fi.LastWriteTime.Day != dtLastWrite.Day || fi.LastWriteTime.Hour != dtLastWrite.Hour || fi.LastWriteTime.Minute != dtLastWrite.Minute || fi.LastWriteTime.Second != dtLastWrite.Second || fi.LastWriteTime.Millisecond != dtLastWrite.Millisecond) { File.Copy(txtFilePath.Text, "copy/" + DateTime.Now.ToString("HHmmss_fff") + fi.Extension.ToLower()); dtLastWrite = fi.LastWriteTime; return; } } }; } catch (Exception ex) { MessageBox.Show(ex.Message); } } /// <summary> /// 选择被监控的文件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnBrowse_Click(object sender, RoutedEventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.CheckFileExists = true; openFileDialog.CheckPathExists = true; openFileDialog.ReadOnlyChecked = false; openFileDialog.Multiselect = false; openFileDialog.Filter = "所有文件|*.*"; openFileDialog.Title = "选择文件"; if ((bool)openFileDialog.ShowDialog()) { this.txtFilePath.Text = openFileDialog.FileName; } } /// <summary> /// 按钮:开始监控 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnStart_Click(object sender, RoutedEventArgs e) { // 检查输入是否合法 if (!File.Exists(this.txtFilePath.Text)) { MessageBox.Show("被监控文件路径非法"); return; } bool b; int interval; b = int.TryParse(this.txtInterval.Text, out interval); if (!b || interval < 100) { MessageBox.Show("快照时间间隔必须是不小于100的整数"); return; } //锁定所有设置项 this.txtFilePath.IsEnabled = false; this.txtInterval.IsEnabled = false; this.rdbSizeOnly.IsEnabled = false; this.rdbTimeOnly.IsEnabled = false; this.btnStart.IsEnabled = false; this.btnStop.IsEnabled = true; // 获取文件信息和计时器时间间隔 lFileSize = -1; dtLastWrite = new DateTime(2000, 1, 1, 0, 0, 0); dsptMon.Interval = new TimeSpan(interval); // 打开计时器 dsptMon.Start(); } /// <summary> /// 按钮:中止监控 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnStop_Click(object sender, RoutedEventArgs e) { // 关闭计时器 dsptMon.Stop(); //解锁所有设置项 this.txtFilePath.IsEnabled = true; this.txtInterval.IsEnabled = true; this.rdbSizeOnly.IsEnabled = true; this.rdbTimeOnly.IsEnabled = true; this.btnStart.IsEnabled = true; this.btnStop.IsEnabled = false; } } }
END
时间: 2024-10-03 23:16:45