因为需要做一个每天定时同步数据的操作,需要把同步的数据用特定的分隔符分割然后写入文件
客户是通过一个工具。来识别我生成的文件,其实就是 | 但必须通过16进制转字符串然后拼接
核心代码如下:
1 /// <summary> 2 /// 获取数据 3 /// </summary> 4 /// <param name="dt"></param> 5 /// <param name="fileName"></param> 6 protected static StringBuilder GetDate(DataTable dt) 7 { 8 StringBuilder datInfo = new StringBuilder(); 9 //if (dt == null || dt.Rows.Count <= 0) return datInfo; 10 DataColumnCollection dColumn = dt.Columns; 11 12 string uh = UnHex("7C1C", "GBK"); 13 for (int i = 0; i < dt.Rows.Count; i++) 14 { 15 foreach (DataColumn col in dColumn) 16 { 17 string val = dt.Rows[i][col.ColumnName].ToString(); 18 datInfo.AppendFormat("{0}{1}", val, uh); 19 } 20 datInfo.AppendFormat("{0}", " "); //一行分隔符 21 } 22 return datInfo; 23 24 } 25 26 ///<summary> 27 /// 从16进制转换成汉字 28 /// </summary> 29 /// <param name="hex"></param> 30 /// <param name="charset">编码,如"utf-8","gb2312"</param> 31 /// <returns></returns> 32 public static string UnHex(string hex, string charset) 33 { 34 //if (hex == null) 35 // throw new ArgumentNullException("hex"); 36 hex = hex.Replace(",", ""); 37 hex = hex.Replace(" ", ""); 38 hex = hex.Replace("\", ""); 39 hex = hex.Replace(" ", ""); 40 if (hex.Length % 2 != 0) 41 { 42 hex += "20";//空格 43 } 44 // 需要将 hex 转换成 byte 数组。 45 byte[] bytes = new byte[hex.Length / 2]; 46 47 for (int i = 0; i < bytes.Length; i++) 48 { 49 try 50 { 51 // 每两个字符是一个 byte。 52 bytes[i] = byte.Parse(hex.Substring(i * 2, 2), 53 System.Globalization.NumberStyles.HexNumber); 54 } 55 catch (Exception ex) 56 { 57 // Rethrow an exception with custom message. 58 //throw new ArgumentException("hex is not a valid hex number!", "hex"); 59 60 File.AppendAllText(timeLog, ex.Message); 61 } 62 } 63 System.Text.Encoding chs = System.Text.Encoding.GetEncoding(charset); 64 return chs.GetString(bytes); 65 }
配置文件:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings> <add name="链接字符串" connectionString="" /> </connectionStrings> <appSettings> <!--定时执行的时间 格式:HH:mm--> <add key="time" value="16:21" /> <!--定时器执行的时间 单位:ms--> <add key="interval" value="2000" /> <!--同步目录的文件,绝对路径--> <add key="exprotFile" value="D:exprotFile" /> </appSettings> </configuration>
服务部分:
using CAS.DataAccess.BaseDAModels; using CMB.RetailSyncData; using System; using System.Collections.Generic; using System.ComponentModel; using System.Configuration; using System.Data; using System.Diagnostics; using System.IO; using System.Linq; using System.ServiceProcess; using System.Text; using System.Threading.Tasks; using System.Timers; using Newtonsoft.Json.Linq; namespace SyncDataService { public partial class Service : ServiceBase { //static DirectoryInfo rootDir = Directory.GetParent(Environment.CurrentDirectory); static string applicatRoot = AppDomain.CurrentDomain.SetupInformation.ApplicationBase.TrimEnd('\'); //日志路径 public static string timeLog = Path.Combine(applicatRoot, "log\") + DateTime.Now.ToString("yyyyMMdd") + ".txt"; Configuration config;public Service() { InitializeComponent(); Init(); } public void Init() { try { InitConfig(); } catch (Exception ex) { WriteLog(ex.Message + " " + ex.StackTrace); } WriteLog("服务初始化成功"); } protected override void OnStart(string[] args) { WriteLog("服务启动"); LoadFromWebservice(); } public void InitConfig() { ExeConfigurationFileMap map = new ExeConfigurationFileMap(); //(引号里面的是你的配置文件的在程序的绝对路径)。 map.ExeConfigFilename = applicatRoot + @"configApp.config"; config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None); } protected override void OnStop() { WriteLog("服务停止"); //this.Stop(); } /// <summary> /// 开启计时器 /// </summary> /// <param name="wait">是否需要延时开启</param> public void LoadFromWebservice(bool wait = false) { /* * 等待一分钟。在开启计时器。 * 防止:同一个时间点重复导出 */ if (wait) System.Threading.Thread.Sleep(1000 * 60);//等待一分钟 //定义一个定时器,并开启和配置相关属性 double interval = double.Parse(config.AppSettings.Settings["interval"].Value); System.Timers.Timer Synctimer = new System.Timers.Timer(interval);//执行任务的周期 Synctimer.Elapsed += new System.Timers.ElapsedEventHandler(Synctimer_Elapsed); Synctimer.Enabled = true; Synctimer.AutoReset = true; } public void Synctimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { Timer timer = (Timer)sender; if (DateTime.Now.ToString("HH:mm") == config.AppSettings.Settings["time"].Value) { //先停止计时器 timer.Enabled = false; int count = 0; try { //开始同步 } catch (Exception ex) { WriteLog(ex.Message + " " + ex.StackTrace); } timer.Dispose(); //释放资源 LoadFromWebservice(true); //重新开启一个计时器 } GC.Collect(); GC.WaitForPendingFinalizers(); } /// <summary> /// 写log /// </summary> /// <param name="msg">message</param> protected void WriteLog(string msg) { File.AppendAllText(timeLog, DateTime.Now.ToString() + ":" + msg + " "); } /// <summary> /// 保存文件 /// </summary> /// <param name="datInfo">内容</param> /// <param name="fileName">前缀</param> /// <param name="exprotTime">导出时间(T-1)</param> /// <param name="count">导出数量</param> public void WriteFile(StringBuilder datInfo, string fileName, DateTime exprotTime, int count) { //string exprot = applicatRoot + @"exprotFile"; string exprot = config.AppSettings.Settings["exprotFile"].Value; if (!Directory.Exists(exprot)) { Directory.CreateDirectory(exprot); } string time = exprotTime.AddDays(-1).ToString("yyyyMMdd"); string DATName = string.Format(exprot + @"{0}{1}.DAT", fileName, time); string CTLName = string.Format(exprot + @"{0}{1}.CTL", fileName, time); if (File.Exists(DATName)) File.Delete(DATName); if (File.Exists(CTLName)) File.Delete(CTLName); //写数据文件 DAT using (StreamWriter writer = new StreamWriter(DATName, true, Encoding.GetEncoding("GBK"))) { writer.Write(datInfo); } //写控制文件 CLT if (File.Exists(DATName)) { FileInfo f = new FileInfo(DATName); long fize = f.Length; string ctlInfo = Path.GetFileName(DATName) + " " + fize + " " + count + " GBK STD_01 "; using (StreamWriter writer = new StreamWriter(CTLName, true, Encoding.GetEncoding("GBK"))) { writer.Write(ctlInfo); } } } } }
服务是不能直接运行的。必须安装。可以用SC执行。关于SC语法。可以网上搜索。比如:
打开cmd 命令提示窗口
创建服务:
//注意 = 号右边有空格
start= auto :开机自动启动
注意事项,每个=号之前 一定不要有空格 =号后面一定要有空格
sc create top1 binpath= "F:cc.exe start= auto"
创建服务后开启服务
sc start top1
停止服务:
sc stop top
删除服务:
注意:如果服务没有停止。删除的话。服务还在。
sc delete top1
添加描述:
sc description top1 "描述"
如果代码有更新,则先停止服务。然后更新。在开启服务
当然,如果觉得麻烦,可以写一个bat文件
创建服务
@echo.SyncDataService服务创建中......
@echo off
@sc create SyncDataService binPath= ""%cd%SyncDataService.exe"
@sc config SyncDataService start= AUTO
@sc description SyncDataService "这里是服务的描述"
@echo off
@echo 创建完毕!
@pause
启动服务:
@echo.SyncDataService服务启动中......
@echo off
@sc start SyncDataService
@echo off
@echo 启动完毕!
@pause
停止服务:
@echo.服务关闭
@echo off
@net stop SyncDataService
@echo off
@echo.关闭结束!
@pause
删除服务:
@echo.服务删除
@echo off
@sc delete SyncDataService
@echo off
@echo.删除结束!
@pause
这仅仅是一个记录。没什么高级部分。。。。。