您现在的位置是:首页 >技术杂谈 >C# 自动备份文件网站首页技术杂谈
C# 自动备份文件
简介C# 自动备份文件
目录
在工作的时候,遇到了需要定时对服务器的文件进行备份的需求,原因是 AP(服务器)上的空间不够了,导致一直在报警空间不足,本文就工作中使用到的程序进行简单的记录,本功能包含如下几个部分:
- 路径配置
- 数据库连接
- 文件移动
- 文件删除
- 文件压缩
- 记录 log
文件目录如下
下面来一个一个介绍。
APBackUpFiles
此方法的主要功能为:
- 文件移动
- 文件删除
- 文件压缩
- 记录 log
代码如下:
using Oracle.DataAccess.Client;
using System;
using System.Configuration;
using System.Data;
using System.IO;
using System.IO.Compression;
namespace APBackUpFilesToDisk
{
class APBackUpFiles
{
static void Main()
{
/*
* 注意将数据库连接改成正式环境
* 注意上线的时候开启文件删除功能
* 注意注释控制台输出的语句
*/
Console.WriteLine(" 现在开始");
Console.WriteLine("正在执行.");
Console.WriteLine("正在执行..");
Console.WriteLine("正在执行...");
Console.WriteLine("执行期间,请勿对文件夹内部文件 移动 / 复制 / 删除 / 插入!");
string sDtaes = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
string sourceFolder = ConfigurationManager.AppSettings["SourcePath"]; // 源文件夹路径
string backupFolder = ConfigurationManager.AppSettings["BackUpPath"]; // 备份文件夹路径
string searchPattern = ConfigurationManager.AppSettings["FilenameSuffix"]; // 文件名匹配模式
// log 文件存储路径,分时间存储
string filename = ConfigurationManager.AppSettings["LogPath"] + "\BackUpFiles_" + sDtaes + ".log";
int iCounts = 0;// 已操作的文件个数
// 文件操作方法 StreamWriter 数据流写入
StreamWriter sws = new StreamWriter(filename, true);
sws.AutoFlush = true;// 强制每行都写入,而不是等待close时候才写入
// 程序开始标志
sws.WriteLine("[Put File start : " + sDtaes + " ===============]");
try
{
// 检查源文件夹是否存在
if (!Directory.Exists(sourceFolder))
{
// 追加写入
sws.WriteLine("源文件夹不存在。");
sDtaes = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
sws.WriteLine("[Put File end : " + sDtaes + " ===============]");
sws.WriteLine("===========================================================");
sws.Close();
return; // 退出程序
}
// 检查备份文件夹是否存在,不存在则创建
if (!Directory.Exists(backupFolder))
{
Directory.CreateDirectory(backupFolder);
}
// 查找匹配的文件并备份
string[] filesToBackup = Directory.GetFiles(sourceFolder, searchPattern);// 默认按照文件名称排序
foreach (string file in filesToBackup)
{
string sControl = file.Substring(file.LastIndexOf("\") + 1, 10);// 取文件名称,即 control lot 信息
iCounts++;// 只要对文件进行了判断,则计数加一
if (bCheckStatus(sControl))
{
// 构造备份文件路径
string backupFilePath = Path.Combine(backupFolder, Path.GetFileName(file));
// 备份文件
File.Copy(file, backupFilePath, true); // 如果目标文件已存在则覆盖
Console.WriteLine("备份文件 {0} 至 {1}", file, backupFilePath);
sws.WriteLine("BackUp File Success :【" + file + "】To【" + backupFilePath + "】");
// 删除已备份的文件
File.Delete(file);
Console.WriteLine("删除文件 {0}", file);
sws.WriteLine("[Delete File Success : " + file + "]");
if (iCounts == 20000) break;
}
else
{
Console.WriteLine("不备份文件 {0} ", sControl);
sws.WriteLine("不备份文件" + sControl + "");
}
}
Console.WriteLine("开始压缩文件...");
sws.WriteLine("开始压缩文件...");
// 压缩本地文件
string startPath = ConfigurationManager.AppSettings["StartPath"];// 需要被压缩的文件夹
string zipPath = ConfigurationManager.AppSettings["ZipPath"] + "\" + sDtaes + ".zip";// 压缩包存储的路径,并为压缩包命名
ZipFile.CreateFromDirectory(startPath, zipPath);
Console.WriteLine("压缩文件成功!");
sws.WriteLine("压缩文件成功!");
Console.WriteLine("开始删除文件...");
sws.WriteLine("开始删除文件...");
// 删除本地文件,节省空间
LocalFileMethods dlf = new LocalFileMethods();
dlf.DeleteLocalTXT(startPath, searchPattern);
Console.WriteLine("删除文件成功!");
sws.WriteLine("删除文件成功!");
sDtaes = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
sws.WriteLine("[Put File end : " + sDtaes + " ===============]");
sws.WriteLine("===========================================================");
sws.WriteLine();
sws.Close();
Console.WriteLine("共执行:" + iCounts + "个文件");
}
catch (Exception ex)
{
Console.WriteLine("[发生异常 : " + ex.Message + "]");
sws.WriteLine("[发生异常 : " + ex.Message + "]");
}
}
/// <summary>
/// 传入文件名称,查询是否满足删除条件
/// </summary>
/// <param name="sControl"></param>
/// <returns></returns>
public static bool bCheckStatus(string sControl)
{
string sSql;
DataTable dt = new DataTable();
// sql 语句
sSql = " select a.XXX from XXX a " +
"where a.XXX like '" + sControl + "%' and a.XXX <> '" + sControl + "'";
// sql 赋值 无参数传入 sql
OracleParameter[] paramATIO = new OracleParameter[] { };
// 执行sql
dt = OracleHelper.ExecuteDataTable(sSql, paramATIO);
// 若有数据,判断所有状态
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
if (dt.Rows[i][0].ToString() != "Terminated" && dt.Rows[i][0].ToString() != "Finished")
{
return false;
}
}
// sql 语句
sSql = " select a.XXX from XXX a " +
"where a.XXX like '" + sControl + "%' and a.XXX <> '" + sControl + "'";
// sql 赋值 无参数传入 sql
paramATIO = new OracleParameter[] { };
// 执行sql
dt = OracleHelper.ExecuteDataTable(sSql, paramATIO);
if (dt.Rows.Count > 0)// 有数据
{
return true;
}
}
else // 若 ASSY 无数据,需要去 FT 查
{
return false;
}
return false;
}
}
}
app.config
这个文件的作用是配置各种参数,包括了各种路径,可以实现在不改变代码的情况下直接修改操作的文件夹,简单的做到了降低耦合,提高代码复用性的作用,需要修改的时候直接改此配置文件即可。
<?xml version="1.0" encoding="utf-8"?>
<!--设定版本号及字符集-->
<configuration>
<appSettings>
<add key="Block" value="1"/>
<!--源文件夹路径,即需要被备份的文件所在的路径-->
<add key="SourcePath" value="C:Test"/>
<!--备份文件夹路径,即需要将源文件备份到哪个文件夹-->
<add key="BackUpPath" value="D:BackUpFiles"/>
<!--需要被压缩的文件夹,即你要把哪个文件夹压缩,一般同备份文件夹路径-->
<add key="StartPath" value="D:BackUpFiles"/>
<!--压缩包存储的路径,并为压缩包命名,即压缩之后的文件放在哪个文件夹-->
<add key="ZipPath" value="D:ips"/>
<!--log 文件存储路径,分时间存储,即 log 文件的储存路径-->
<add key="LogPath" value="D:APBackUpFilesToDiskLogs"/>
<!--文件名匹配模式,即你要从源文件夹中筛选哪些后缀的文件-->
<add key="FilenameSuffix" value="*.LOT"/>
<add key="ClientSettingsProvider.ServiceUri" value=""/>
</appSettings>
<!--默认配置,不用管-->
<system.web>
<membership defaultProvider="ClientAuthenticationMembershipProvider">
<providers>
<add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri=""/>
</providers>
</membership>
<roleManager defaultProvider="ClientRoleProvider" enabled="true">
<providers>
<add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400"/>
</providers>
</roleManager>
</system.web>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup>
</configuration>
OracleHelper
此类的作用是连接数据库,在里面配置数据库连接,后面直接调用此方法即可实现简单的数据库操作(CRUD)。
using Oracle.DataAccess.Client;
using System.Data;
namespace APBackUpFilesToDisk
{
class OracleHelper
{
private static string connStr = "User Id=XXX;Password=XXX;" +
"Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=XX.XX.XX.XX)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=XXXX)))";
#region 执行SQL语句,返回受影响行数
public static int ExecuteNonQuery(string sql, params OracleParameter[] parameters)
{
using (OracleConnection conn = new OracleConnection(connStr))
{
conn.Open();
using (OracleCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddRange(parameters);
int i = cmd.ExecuteNonQuery();
conn.Close();
return i;
}
}
}
#endregion
#region 执行SQL语句,返回DataTable;只用来执行查询结果比较少的情况
public static DataTable ExecuteDataTable(string sql, params OracleParameter[] parameters)
{
using (OracleConnection conn = new OracleConnection(connStr))
{
conn.Open();
using (OracleCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddRange(parameters);
OracleDataAdapter adapter = new OracleDataAdapter(cmd);
DataTable datatable = new DataTable();
adapter.Fill(datatable);
conn.Close();
return datatable;
}
}
}
#endregion
}
}
LocalFileMethods
本地文件操作的方法。
using System;
using System.IO;
namespace APBackUpFilesToDisk
{
class LocalFileMethods
{
public void DeleteLocalTXT(string startPath,string searchPattern)
{
try
{
string[] txtList = Directory.GetFiles(startPath, searchPattern);
// 删除源文件
foreach (string f in txtList)
{
File.Delete(f);
}
}
catch (DirectoryNotFoundException dirNotFound)
{
Console.WriteLine(dirNotFound.Message);
}
}
}
}
LogFile
记录 log 的方法。
using System;
using System.IO;
namespace APBackUpFilesToDisk
{
class LogFile
{
private string ToFileNmae;
//日志存储路径
public void Logfile(string path)
{
this.ToFileNmae = path;
}
/// <summary>
/// 创建日志
/// </summary>
/// <param name="message">日志信息</param>
/// <param name="title">日志标题</param>
public void Log(string message)
{
string path = this.ToFileNmae;
string filename = path + "\Log.txt";
string cont = "";
FileInfo fileInf = new FileInfo(filename);
if (File.Exists(filename))//如何文件存在 则在文件后面累加
{
FileStream myFss = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
StreamReader r = new StreamReader(myFss);
cont = r.ReadToEnd();
r.Close();
myFss.Close();
}
#region 生成文件日志
FileStream myFs = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
StreamWriter n = new StreamWriter(myFs);
n.WriteLine(cont);
n.WriteLine(DateTime.Now.ToString() + ":" + message);
n.Close(); myFs.Close();
if (fileInf.Length >= 1024 * 1024 * 200)
{
string NewName = path + "Log" + time() + ".txt";
File.Move(filename, NewName);
}
#endregion
}
/// <summary>
/// 系统时间
/// </summary>
/// <returns></returns>
///
public string time()
{
string dNow = DateTime.Now.ToString().Trim().Replace("/", "").Replace(":", "");
string fileName = dNow.ToString();
return fileName;
}
}
}
packages.config
默认配置,不管他。
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Oracle.DataAccess.x86.4" version="4.112.3" targetFramework="net45" />
</packages>
ReadFile
读取文件的操作,与写 log 等相互配合。
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Text.RegularExpressions;
namespace APBackUpFilesToDisk
{
class ReadFile
{
public static void Movefile(string filename, string type)
{
try
{
string sDir = ConfigurationManager.AppSettings[type];
string sCommonPath = ConfigurationManager.AppSettings["Common"];
string sDirSource = System.IO.Path.GetDirectoryName(filename);
string[] sDirDetail = Regex.Split(sDirSource, sCommonPath);
string sDirCus = sDirDetail[1];
sDir = sDir + @"" + sDirCus;
string sFilename = System.IO.Path.GetFileName(filename);
if (!Directory.Exists(sDir))
{
Directory.CreateDirectory(sDir);
}
if (File.Exists(Path.Combine(sDir, sFilename)))
{
File.Move(Path.Combine(sDir, sFilename), Path.Combine(sDir, sFilename + DateTime.Now.ToString().Trim().Replace("/", "").Replace(":", "")));
}
File.Move(filename, Path.Combine(sDir, sFilename));
}
catch (Exception ex)
{
WriteLog("ReaderMappingfile: " + ex.Message.ToString());
}
}
public static void Backupfile(string filename)
{
try
{
string sDir = System.IO.Path.GetDirectoryName(filename);
string sFilename = System.IO.Path.GetFileName(filename);
if (!Directory.Exists(Path.Combine(sDir, "backup")))
{
Directory.CreateDirectory(Path.Combine(sDir, "backup"));
}
if (File.Exists(Path.Combine(sDir, "backup\" + sFilename)))
{
File.Move(Path.Combine(sDir, "backup\" + sFilename), Path.Combine(sDir, "backup\" + sFilename + DateTime.Now.ToString().Trim().Replace("/", "").Replace(":", "")));
}
File.Move(filename, Path.Combine(sDir, "backup\" + sFilename));
}
catch (Exception ex)
{
WriteLog("ReaderMappingfile: " + ex.Message.ToString());
}
}
public Dictionary<string, string> NewOld2D(string filename)
{
Dictionary<string, string> DicMapping = new Dictionary<string, string>();
try
{
string sBindetail = File.ReadAllText(filename);
string[] s2DAll_list = Regex.Split(sBindetail.TrimEnd(), "");
for (int i = 0; i < s2DAll_list.Length; i++)
{
DicMapping.Add(s2DAll_list[i].Split(',')[0].ToString(), s2DAll_list[i].Split(',')[1].TrimEnd().ToString());
}
}
catch (Exception ex)
{
WriteLog("NewOld2D: " + ex.Message.ToString());
}
return DicMapping;
}
public static void WriteLog(string smessage)
{
try
{
LogFile log1 = new LogFile();
string sLogPath = System.AppDomain.CurrentDomain.BaseDirectory.ToString() + "\LOG";
if (!Directory.Exists(sLogPath))
{
Directory.CreateDirectory(sLogPath);
}
log1.Logfile(sLogPath);
log1.Log(smessage);
}
catch (Exception ex)
{
}
}
}
}
如何发布
将代码路径下的这四个文件复制到需要执行的 AP 上面即可。
直接双击 .exe 文件即可执行,如何设定任务计划程序参考此文:设定任务计划程序
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。