数据备份(异步拷贝数据)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.IO;
using System.Threading;

namespace Statistics
{
    public partial class frmDataManage : Form
    {
        private static readonly String bakFileDir = ConfigManager.GetAppConfig("bakPathDir");
        private String bakFilePath = "";
        public frmDataManage()
        {
            InitializeComponent();
            this.txtBackUppath.Text = ConfigManager.GetAppConfig("bakPathDir");
        }

        private dataState state = new dataState(0, 0, null, null, CommonUse.DB_OPERATE.DB_NONE);
        private void btn_backup_Click(object sender, EventArgs e)
        {
            //检测数据库文件是否存在
            if (!File.Exists(CommonUse.strFilePathName))
            {
                MessageBox.Show("数据库备份失败,请检查数据库文件是否存在!", "提示",
                    MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);
                return;
            }

            //检测数据库文件是否损坏

            //检测磁盘空间是否足够
            long diskFreeSpace = CommonFunction.GetAvailableSizeOfDisk(@"G:/");
            long backedupFileSize = CommonFunction.GetSizeOfFile(CommonUse.strFilePathName);
            backedupFileSize += 10 * 1024;

            if (backedupFileSize > diskFreeSpace)
            {
                MessageBox.Show("G盘空间不足,请清理完磁盘空间后再恢复!", "提示",
                    MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);
                return;
            }

            if (!Directory.Exists(bakFileDir))
            {
                Directory.CreateDirectory(bakFileDir);
            }

            bakFilePath = bakFileDir + DateTime.Now.ToShortDateString() + @"life.bak";
            if (File.Exists(bakFilePath))
            {
                DialogResult result = DialogResult.Yes;
                result = MessageBox.Show("该备份文件已存在,是否替换原有文件?", "确认",
                    MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
                this.Refresh();

                if (result == DialogResult.Yes)
                {
                    RenameFileName(bakFilePath);
                }
                else
                {
                    return;
                }
            }

            FileStream tmpReader = new FileStream(CommonUse.strFilePathName, FileMode.Open, FileAccess.Read);
            FileStream tmpWriter = new FileStream(bakFilePath, FileMode.Append, FileAccess.Write);

            state.totalFileSize = (int)tmpReader.Length;
            state.curFilePos = 0;
            state.fsReader = tmpReader;
            state.fsWriter = tmpWriter;
            state.dbOperate = CommonUse.DB_OPERATE.DB_BACKUP;

            InitProgressBar(state.totalFileSize, state.curFilePos);

            state.fsReader.BeginRead(state.buffer, 0, state.buffer.Length, new AsyncCallback(AsyncCopyFile), state);
        }

        private void InitProgressBar(int totalFileSize, int curFilePos)
        {
            pb_process.Visible = true;
            pb_process.Maximum = totalFileSize;
            pb_process.Value = curFilePos;
            pb_process.Refresh();
        }

        private void RenameFileName(String fileName)
        {
            if (File.Exists(fileName))
            {
                if (File.Exists(fileName + "tmp"))
                {
                    File.Delete(fileName + "tmp");
                }
                File.Move(fileName, fileName + "tmp");
            }
        }
        private void ReverseFileName(String fileName)
        {
            if (File.Exists(fileName + "tmp"))
            {
                if (File.Exists(fileName + "tmp"))
                {
                    File.Delete(fileName + "tmp");
                }
                File.Move(fileName + "tmp", fileName);
            }
        }

        private void AsyncCopyFile(IAsyncResult ar)
        {
            try
            {
                dataState tempState = (dataState)ar.AsyncState;

                int readedLength;
                lock (tempState.fsReader)
                {
                    readedLength = tempState.fsReader.EndRead(ar);
                }

                tempState.fsWriter.Write(tempState.buffer, 0, readedLength);
                tempState.curFilePos += readedLength;

                MethodInvoker m = new MethodInvoker(SynchProgressBar);
                BeginInvoke(m);

                if (tempState.curFilePos >= tempState.totalFileSize)
                {
                    successProcess();
                    return;
                }

                lock (tempState.fsReader)
                {
                    tempState.fsReader.BeginRead(tempState.buffer, 0, tempState.buffer.Length, new AsyncCallback(AsyncCopyFile), tempState);
                }
            }
            catch (System.Exception ex)
            {
                exceptionProcess();
                return;
            }
           
        }

        private void SynchProgressBar()
        {
            this.pb_process.Value = state.curFilePos;
            if (state.curFilePos == state.totalFileSize)
            {
                this.pb_process.Visible = false;
            }
        }

        private void successProcess()
        {
            state.closeFile();

            if (state.dbOperate == CommonUse.DB_OPERATE.DB_BACKUP)
            {
                MessageBox.Show("数据成功备份到" + bakFilePath + "中!", "提示",
                    MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);

                if (File.Exists(bakFilePath + "tmp"))
                {
                    File.Delete(bakFilePath + "tmp");
                }
            }
            else if (state.dbOperate == CommonUse.DB_OPERATE.DB_RESOTRE)
            {
                MessageBox.Show("数据库恢复成功!", "提示",
                    MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);
                if (File.Exists(CommonUse.strFilePathName + "tmp"))
                {
                    File.Delete(CommonUse.strFilePathName + "tmp");
                }
            }
        }

        private void exceptionProcess()
        {
            state.closeFile();

            state.curFilePos = state.totalFileSize;
            MethodInvoker m = new MethodInvoker(SynchProgressBar);
            BeginInvoke(m);

            if (state.dbOperate == CommonUse.DB_OPERATE.DB_BACKUP)
            {

                MessageBox.Show("数据库备份失败!", "提示",
                    MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);

                if (File.Exists(bakFilePath))
                {
                    File.Delete(bakFilePath);
                }
                ReverseFileName(bakFilePath);

            }
            else if (state.dbOperate == CommonUse.DB_OPERATE.DB_RESOTRE)
            {
                MessageBox.Show("数据库恢复失败!", "提示",
                    MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);
                if (File.Exists(CommonUse.strFilePathName))
                {
                    File.Delete(CommonUse.strFilePathName);
                }
                ReverseFileName(CommonUse.strFilePathName);
            }
        }

        private void btnSelectFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "bak Files (*.bak)|*.bak";
            dlg.InitialDirectory = bakFileDir;


            this.txtRestorePath.Text = "";
            if (dlg.ShowDialog() == DialogResult.OK)
            {

                if (dlg.FileName.Length < 4)
                {
                    MessageBox.Show("请选择数据库文件!", "提示",
                        MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);
                    return;
                }

                string str = dlg.FileName.Substring(dlg.FileName.Length - 4);
                str = str.ToLower();
                if (!str.Equals(".bak"))
                {
                    MessageBox.Show("请选择数据库文件!", "提示",
                        MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);
                    return;
                }
                this.txtRestorePath.Text = dlg.FileName;

            }
            else
            {
                this.txtRestorePath.Text = "";
            }
        }

        private String restoreFilePath = "";
        private void btnRestore_Click(object sender, EventArgs e)
        {
            this.txtRestorePath.Text = this.txtRestorePath.Text.TrimEnd();
            if (this.txtRestorePath.Text == "")
            {
                MessageBox.Show("路径不能为空!", "提示",
                    MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);
                return;
            }

            restoreFilePath = this.txtRestorePath.Text;

            long diskFreeSpace = CommonFunction.GetAvailableSizeOfDisk(CommonUse.strFilePathName.Substring(0, 3));
            long dbFileSize = CommonFunction.GetSizeOfFile(restoreFilePath);

            if (dbFileSize > diskFreeSpace)
            {
                MessageBox.Show("磁盘空间不足,请清理完磁盘空间后再恢复!", "提示",
                    MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);
                return;
            }

            DialogResult result = MessageBox.Show("确定需要恢复数据库吗?", "确认",
                MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
            this.Refresh();

            if (result != DialogResult.Yes)
            {
                return;
            }

            RenameFileName(CommonUse.strFilePathName);


            FileStream tmpReader = new FileStream(restoreFilePath, FileMode.Open, FileAccess.Read);
            FileStream tmpWriter = new FileStream(CommonUse.strFilePathName, FileMode.Append, FileAccess.Write);

            state.totalFileSize = (int)tmpReader.Length;
            state.curFilePos = 0;
            state.fsReader = tmpReader;
            state.fsWriter = tmpWriter;
            state.dbOperate = CommonUse.DB_OPERATE.DB_RESOTRE;

            InitProgressBar(state.totalFileSize, state.curFilePos);

            state.fsReader.BeginRead(state.buffer, 0, state.buffer.Length, new AsyncCallback(AsyncCopyFile), state);
        }

        private void btn_delete_Click(object sender, EventArgs e)
        {
            DateTime start = new DateTime(dtp_startDate.Value.Year, dtp_startDate.Value.Month, dtp_startDate.Value.Day);
            DateTime end = new DateTime(dtp_endDate.Value.Year, dtp_endDate.Value.Month, dtp_endDate.Value.Day);

            if (start.CompareTo(end) > 0)
            {
                MessageBox.Show("起始时间应该小于结束时间!", "提示",
                    MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);
                return;
            }

            DialogResult dg = MessageBox.Show("确定需要删除该时间段数据吗?删除请备份数据库", "确认",
                MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);

            if (dg == DialogResult.No)
            {
                return;
            }

            try
            {
                DBOperate.Instance.DeleteTable(start, end);
                CommonUse.frmmain.showStatus("删除成功");
            }
            catch (System.Exception ex)
            {
                CommonUse.frmmain.showStatus(ex.Message);
            }
        }

    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;

namespace Statistics
{
    class dataState
    {
        public Byte[] buffer;
        public int totalFileSize;
        public int curFilePos;
        public FileStream fsReader = null;
        public FileStream fsWriter = null;
        public CommonUse.DB_OPERATE dbOperate;

        public dataState(int totalFileSize, int curFilePos, FileStream fsReader, FileStream fsWriter,
            CommonUse.DB_OPERATE dbOperate)
        {
            this.buffer = new Byte[1024];
            this.totalFileSize = totalFileSize;
            this.curFilePos = curFilePos;
            this.fsReader = fsReader;
            this.fsWriter = fsWriter;
            this.dbOperate = dbOperate;
        }

        public void closeFile()
        {
            if (fsReader != null)
            {
                fsReader.Close();
            }
            if (fsWriter != null)
            {
                fsWriter.Close();
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;
using System.Runtime.InteropServices;

namespace Statistics
{
    class CommonFunction
    {
        [DllImport("kernel32.dll", EntryPoint = "GetDiskFreeSpaceEx")]
        public static extern int GetDiskFreeSpaceEx(string lpRootPathName,
            out long lpFreeBytesAvailable,
            out long lpTotalNumberOfBytes,
            out long lpTotalNumberOfFreeBytes);

        public static long GetAvailableSizeOfDisk(String dir)
        {
            long lpFreeBytesAvailable, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes;

            try
            {
                GetDiskFreeSpaceEx(dir,
                    out lpFreeBytesAvailable,
                    out lpTotalNumberOfBytes,
                    out lpTotalNumberOfFreeBytes);
            }

            catch (Exception ex)
            {
                throw ex;
            }

            return (long.Parse(lpFreeBytesAvailable.ToString()) / 1024);
        }

        /// <summary>
        /// 获取文件大小
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        public static long GetSizeOfFile(string filename)
        {
            long fileLength = 0;

            try
            {
                FileInfo info = new FileInfo(filename);
                fileLength = info.Length;
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return (long.Parse(fileLength.ToString()) / 1024);
        }

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>