C#開發的定時自動拷貝檔案到別處,並刪除過期備份檔案,支援網路上的芳鄰拷貝
開發工具VS2013 .net 框架 2.0
SQL server的備份檔案只可以備份在本機,只有一份,這個軟體可以定時把備份檔案拷貝到別的機器,作為另外的備份,還可以在成功備份後自動刪除過期的檔案,沒有成功備份,不刪除過期檔案,以免誤刪,除非手動刪除。
拷貝檔案過程中沒有進度條提示。
寫了4個類,沒寫欄位和屬性,只寫方法,很簡單。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Ini.cs //讀寫配置檔案,使用設定可以儲存下來,下次開啟軟體,不用重新設定
using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace AutoCopy { class Ini { [DllImport("kernel32")] private static extern long WritePrivateProfileString(string section, string key, string val, string filePath); [DllImport ("kernel32")] private static extern int GetPrivateProfileString(string section, string key, string def,StringBuilder retVal, int size,string filePath); /// <summary> /// 讀取ini /// </summary> /// <param name="group">資料分組</param> /// <param name="key">關鍵字</param> /// <param name="default_value"></param> /// <param name="filepath">ini檔案地址</param> /// <returns>關鍵字對應的值,沒有時用預設值</returns> public static string readini(string group, string key, string default_value, string filepath) { StringBuilder temp = new StringBuilder(); GetPrivateProfileString(group,key,default_value,temp, 255, filepath); return temp.ToString(); } /// <summary> /// 儲存ini /// </summary> /// <param name="group">資料分組</param> /// <param name="key">關鍵字</param> /// <param name="value">關鍵字對應的值</param> /// <param name="filepath">ini檔案地址</param> public static void writeini(string group, string key, string value, string filepath) { WritePrivateProfileString(group, key, value, filepath); } } }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
FileOprater.cs //檔案操作類,
using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; using System.Windows.Forms; namespace AutoCopy { class FileOprater { public FileOprater(){} /// <summary> /// 讀取路徑上的檔案列表 /// </summary> /// <param name="Path">檔案路徑</param> /// <param name="compare"> == 或者 >= </param> /// <param name="days">用numberUpDown的值</param> /// <returns></returns> public ArrayList getFileList(string Path, string compare, int days) { try { string[] dir = Directory.GetFiles(Path); ArrayList _fileList = new ArrayList(); for (int dirIndex = 0; dirIndex < dir.Length; dirIndex++) { DateTime fileLastWriteTime = File.GetLastWriteTime(dir[dirIndex].ToString()); TimeSpan timespan = DateTime.Today.Date - fileLastWriteTime.Date; if (compare == "==") { if (timespan.Days == 0) { _fileList.Add(dir[dirIndex].ToString()); } } else { //TimeSpan timespan = DateTime.Today.Date - fileLastWriteTime.Date; if (timespan.Days >= days) { _fileList.Add(dir[dirIndex].ToString()); } } } return _fileList; } catch(Exception e) { MessageBox.Show(e.ToString(),"錯誤",MessageBoxButtons.OK,MessageBoxIcon.Error); return null; } } /// <summary> /// 拷貝檔案,用FileStream buffer來寫入,大檔案也沒問題 /// </summary> /// <param name="SourcePath">原始檔路徑</param> /// <param name="DestinyPath">目標檔案路徑</param> public void CopyFiles(string SourcePath, string DestinyPath) { //1建立一個負責讀取的流 using (FileStream fsRead = new FileStream(SourcePath, FileMode.Open, FileAccess.Read)) {//建立一個負責寫入的流 using (FileStream fsWrite = new FileStream(DestinyPath, FileMode.OpenOrCreate, FileAccess.Write)) { byte[] buffer = new byte[1024 * 1024 * 5]; while (true) { int r = fsRead.Read(buffer, 0, buffer.Length); //如果返回一個0,就意味什麼都沒有讀取到,讀取完了 if (r == 0) { break; } fsWrite.Write(buffer, 0, r); } } } } public void DeleteFiles(string Path) { File.Delete(Path); } } }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
MyListBox.cs
//把檔案顯示在列表框的類
using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Windows.Forms; using System.Collections; namespace AutoCopy { class MyListBox { public MyListBox() { } internal Boolean showFilesList(ArrayList fileList,ListBox listbox ) { //定義陣列,用於儲存檔案路徑 if (fileList != null) { for (int index = 0; index < fileList.Count; index++) { listbox.Items.Add(fileList[index].ToString()); } return true; } else return false; } } }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
LogWriter.cs
//最後的這個是寫入日誌檔案的類。
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace AutoCopy
{
class LogWriter
{
public LogWriter() { }
internal void writeLog(string str)
{
string AppPath = System.Windows.Forms.Application.StartupPath + "\\Log.txt";
if (!File.Exists(AppPath))
{
File.CreateText(AppPath);
}
using (FileStream fs = new FileStream(AppPath, FileMode.Append, FileAccess.Write))
{
Byte[] info =
new UTF8Encoding(true).GetBytes(DateTime.Now.ToString() + " "+str+"\r\n");
// Add some information to the file.
fs.Write(info, 0, info.Length);
}
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Form1.cs //介面裡的操作程式碼寫的有點多,顯得有點零亂。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections;
namespace AutoCopy
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//原始檔目錄瀏覽按鈕
private void buttonSource_Click(object sender, EventArgs e)
{
folderBrowserDialog1.ShowDialog();
textBoxSource.Text = folderBrowserDialog1.SelectedPath.ToString();
}
//目標檔案目錄瀏覽按鈕
private void buttonDestiny_Click(object sender, EventArgs e)
{
folderBrowserDialog1.ShowDialog();
textBoxDestiny.Text = folderBrowserDialog1.SelectedPath.ToString();
}
//新建FileOprater物件
FileOprater fo=new FileOprater();
//新建MyListBox物件
MyListBox mylistbox=new MyListBox();
//新建LogWriter物件
LogWriter lw = new LogWriter();
//新建Ini物件
//Ini ini = new Ini();
//托盤區圖示功能
private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (WindowState == FormWindowState.Minimized)
{
//還原窗體顯示
WindowState = FormWindowState.Normal;
//啟用窗體並給予它焦點
this.Activate();
//工作列區顯示圖示
this.ShowInTaskbar = true;
//托盤區圖示隱藏
notifyIcon1.Visible = false;
}
}
//隱藏程式視窗到托盤區
private void Form1_SizeChanged(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Minimized)
{
//隱藏工作列區圖示
this.ShowInTaskbar = false;
//圖示顯示在托盤區
notifyIcon1.Visible = true;
}
}
//關閉程式確認對話方塊
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show("是否確定退出程式?","退出",MessageBoxButtons.OKCancel,MessageBoxIcon.Question) == DialogResult.OK)
{
//關閉所有的程序
this.Dispose();
this.Close();
}
else
{
e.Cancel = true;
}
}
private void buttonOK_Click(object sender, EventArgs e)
{
TodayFileslistBox.Items.Clear(); //清空列表框
mylistbox.showFilesList(fo.getFileList(textBoxSource.Text.Trim(),"==",0),TodayFileslistBox);//顯示檔案列表在列表框
if (TodayFileslistBox.Items != null) //如果列表不為空(有檔案)
{
for (int i = 0; i < TodayFileslistBox.Items.Count; i++) //迴圈
{
string strName = TodayFileslistBox.Items[i].ToString().Substring(TodayFileslistBox.Items[i].ToString().LastIndexOf("\\"));
try
{
StatusLabel2.Text = strName + "正在複製";
fo.CopyFiles(TodayFileslistBox.Items[i].ToString(), textBoxDestiny.Text + strName);
StatusLabel2.Text = strName + " 複製完成";
lw.writeLog(TodayFileslistBox.Items[i].ToString() + " 複製成功");//寫入日誌檔案
//以上程式碼跟Timer1的執行程式碼有重複,下面也有說明
}
catch (Exception ex)
{
StatusLabel2.Text = "備份過程出錯,請檢視日誌檔案Log.txt";
lw.writeLog(ex.ToString());
}
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
updateFileListlabel();
updateStatusLabel();
StatusLabel2.Text = "";
//測試讀寫set.ini檔案的程式碼
//string value = Ini.readini("group1", "source", "default_value1", ".\\set.ini");
//Ini.writeini("group2", "key2", value, ".\\set.ini");
InitializeSets();
}
private void InitializeSets()
{
textBoxSource.Text = Ini.readini("group1", "source", "I:\\backup", ".\\set.ini");
textBoxDestiny.Text = Ini.readini("group1", "destiny", "D:\\backup", ".\\set.ini");
checkBoxDel.Checked = Convert.ToBoolean(Ini.readini("group1", "deleteChecked", "true", ".\\set.ini"));
DaysNumericUpDown.Value = Convert.ToDecimal(Ini.readini("group1", "days", "3", ".\\set.ini"));
dateTimePicker1.Value = Convert.ToDateTime(Ini.readini("group1", "actionTime", "20:00:00", ".\\set.ini"));
}
private void updateStatusLabel()
{
StatusLabel1.Text="備份時間:"+dateTimePicker1.Value.ToShortTimeString();
}
//重新整理N天前檔案列表標籤
private void updateFileListlabel()
{
FileListlabel.Text = DaysNumericUpDown.Value + "天前的檔案列表:";
}
//更改天數時,重新整理N天前檔案列表標籤
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
updateFileListlabel();
Ini.writeini("group1", "days", DaysNumericUpDown.Value.ToString(), ".\\set.ini");
}
private void buttonUpdateTodayFileList_Click(object sender, EventArgs e)
{
//清空列表
TodayFileslistBox.Items.Clear();
ArrayList filelist = fo.getFileList(textBoxSource.Text.Trim(),"==",0);
mylistbox.showFilesList(filelist,TodayFileslistBox);
}
private void buttonUpdateNdaysFileList_Click(object sender, EventArgs e)
{
#region 模組化的程式碼,沒用
//FillListBox(NdaysBeforeFilesListBox, textBoxDestiny.Text.Trim(), NdayBeforeFileslabel,Convert.ToInt16(DaysNumericUpDown.Value),"<=");
#endregion
fillNdaysListBox();
}
private void fillNdaysListBox()
{
NdaysBeforeFilesListBox.Items.Clear();
ArrayList filelist = fo.getFileList(textBoxDestiny.Text.Trim(), "=>", Convert.ToInt16(DaysNumericUpDown.Value));
mylistbox.showFilesList(filelist, NdaysBeforeFilesListBox);
}
private void timer1_Tick(object sender, EventArgs e)
{
#region MyRegion
if (DateTime.Now.ToShortTimeString() == dateTimePicker1.Value.ToShortTimeString())
{
//顯示今天檔案在列表框
TodayFileslistBox.Items.Clear();
mylistbox.showFilesList(fo.getFileList(textBoxSource.Text.Trim(), "==", 0), TodayFileslistBox);
//拷貝檔案
if (TodayFileslistBox.Items != null) //如果沒有當天的檔案可複製,剛不刪除舊已備份的檔案
{
for (int i = 0; i < TodayFileslistBox.Items.Count; i++)
{
string strName = TodayFileslistBox.Items[i].ToString().Substring(TodayFileslistBox.Items[i].ToString().LastIndexOf("\\"));
try
{
StatusLabel2.Text = "正在複製檔案:" + strName;
fo.CopyFiles(TodayFileslistBox.Items[i].ToString(), textBoxDestiny.Text + strName);
StatusLabel2.Text = strName+ " 複製完成";
lw.writeLog(TodayFileslistBox.Items[i].ToString() + " 複製成功");//寫入日誌檔案
//以上程式碼跟“拷貝檔案”按鈕的程式碼有重複,之所以不能重構成方法,是因為下面兩行Timer1程式碼包含了刪除過期檔案的程式碼。
//暫時沒找到更好的方法,以後學習到更好的方法再改正。也希望同學們不吝賜教。
}
catch (Exception ex)
{
StatusLabel2.Text = "備份過程出錯,請檢視日誌檔案Log.txt";
lw.writeLog(ex.ToString());
}
}
//如果沒有當天的檔案可複製,剛不刪除舊已備份的檔案
//顯示N天前的檔案在列表框
fillNdaysListBox();
//刪除檔案
delfiles();
}
#endregion
}
}
private void buttonDelete_Click(object sender, EventArgs e)
{
if (MessageBox.Show("你確定要刪除檔案嗎,刪除後不可恢復!!","確定刪除!!",MessageBoxButtons.YesNoCancel,MessageBoxIcon.Warning,MessageBoxDefaultButton.Button3) == DialogResult.Yes)
{
if (MessageBox.Show("確定要刪!,不可恢復哦!!", "真的要刪除!!", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button3) == DialogResult.Yes)
{
fillNdaysListBox();
delfiles();
}
}
}
private void delfiles()
{
if (checkBoxDel.Checked)
{
for (int i = 0; i < NdaysBeforeFilesListBox.Items.Count; i++)
{
string path = NdaysBeforeFilesListBox.Items[i].ToString();
try
{
fo.DeleteFiles(path);
StatusLabel2.Text = path + " 刪除成功";
lw.writeLog(path + " 刪除成功");
}
catch (Exception e)
{
StatusLabel2.Text = path + " 刪除失敗,請檢視日誌檔案!";
lw.writeLog(e.ToString());
}
}
}
}
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
updateStatusLabel();
Ini.writeini("group1", "actionTime", dateTimePicker1.Value.ToShortTimeString(), ".\\set.ini");
}
private void textBoxSource_TextChanged(object sender, EventArgs e)
{
Ini.writeini("group1", "source", textBoxSource.Text.Trim() , ".\\set.ini");
}
private void textBoxDestiny_TextChanged(object sender, EventArgs e)
{
Ini.writeini("group1", "destiny", textBoxDestiny.Text.Trim(), ".\\set.ini");
}
private void checkBoxDel_CheckedChanged(object sender, EventArgs e)
{
Ini.writeini("group1", "deleteChecked", checkBoxDel.Checked.ToString(), ".\\set.ini");
}
}
}
原始碼下載:https://files.cnblogs.com/files/YJkong/AutoCopy.rar
注意:本內容來自http://www.cnblogs.com/YJkong/articles/9277099.html