using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.IO;
using System.Text.RegularExpressions;
namespace FLY.Thick.RemoteHistory
{
public interface IFlyData
{
DateTime Time { get; set; }
string GetHeader();
string ToString();
bool TryParse(string header_str, string str);
}
///
/// 历史数据, 保存格式为 csv
///
///
public interface IHistory
: IRemoteHistory
where T : IFlyData
{
///
/// 设置自定义的部分文件名,不能出现特殊符号 “.” 都不可以
///
string FileNameCustom{get;set;}
///
/// 数据添加
///
///
void AddRange(IEnumerable t_array);
void Add( T t);
///
/// 根路径
///
string RootPath{get;set;}
}
///
/// 历史数据, 保存格式为 csv
///
public class History : IHistory
where T : IFlyData
{
private List datas = new List();
///
/// 已经保存了数据的日期,
///
private List dateInRootPath = new List();
public History(string rootpath)
{
KeeyDay = 180;
SaveRows = 200;
RootPath = rootpath;
FileNameCustom = null;
CurrPath = null;
CurrRows = 0;
InitKeepDay();
}
#region IHistory 成员
private string filenamecustom;
///
/// 设置自定义的部分文件名,不能出现特殊符号 “.” 都不可以
///
public string FileNameCustom
{
get
{
return filenamecustom;
}
set
{
if (filenamecustom != value)
{
Flush();
filenamecustom = value;
NotifyPropertyChanged("FileNameCustom");
}
}
}
private int currdays = 0;
///
/// 当前保存的数据天数
///
public int CurrDays { get { return currdays; }
protected set {
if (currdays != value)
{
currdays = value;
NotifyPropertyChanged("CurrDays");
}
}
}
private int keeyday;
///
/// 数据能保存的天数
///
public int KeeyDay
{
get
{
return keeyday;
}
set
{
if (value <= 0)
value = 1;
if (keeyday != value)
{
keeyday = value;
NotifyPropertyChanged("KeeyDay");
}
}
}
private string rootpath;
///
/// 根路径
///
public string RootPath
{
get
{
return rootpath;
}
set
{
if (rootpath != value)
{
rootpath = value;
NotifyPropertyChanged("RootPath");
}
}
}
private int saverows;
///
/// 多少行保存一次
///
public int SaveRows
{
get
{
return saverows;
}
set
{
if (saverows != value)
{
saverows = value;
NotifyPropertyChanged("SaveRows");
}
}
}
private int currrows;
///
/// 当前总行数
///
public int CurrRows
{
get
{
return currrows;
}
set
{
if (currrows != value)
{
currrows = value;
NotifyPropertyChanged("CurrRows");
}
}
}
private string currpath=null;
public string CurrPath
{
get
{
return currpath;
}
set
{
if (currpath != value)
{
currpath = value;
NotifyPropertyChanged("CurrPath");
}
}
}
#endregion
#region IHistory
void CreateCurrPath()
{
if (CurrPath == null)
{
//创建路径
DateTime dt = datas.First().Time;
string dirpath = RootPath + @"\" + dt.ToString(@"yyyy\\MM\\dd");
Directory.CreateDirectory(dirpath);
Keep(dt);
if (string.IsNullOrEmpty(FileNameCustom))
{
CurrPath = dirpath + @"\" + dt.ToString("HH_mm_ss") + ".csv";
}
else
{
CurrPath = dirpath + @"\" + dt.ToString("HH_mm_ss") + "_" + FileNameCustom + ".csv";
}
}
}
public void Flush()
{
if (datas.Count() == 0)
return;
if (string.IsNullOrEmpty(CurrPath))
{
CreateCurrPath();
}
//以附加的方式打开只写文件。
//若文件不存在,则会建立该文件,
//如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。
StreamWriter sw = new StreamWriter(CurrPath, true, Encoding.GetEncoding("GB2312"));
sw.WriteLine(datas[0].GetHeader());
for (int i = 0; i < datas.Count; i++)
sw.WriteLine(datas[i].ToString());
datas.Clear();
sw.Flush();
sw.Close();
CurrRows = 0;
CurrPath = null;
}
public void AddRange(IEnumerable t_array)
{
datas.AddRange(t_array);
UpdateAdd();
}
public void Add(T t)
{
datas.Add(t);
UpdateAdd();
}
void UpdateAdd()
{
CurrRows = datas.Count;
if ((CurrRows >= 1) && (CurrPath == null))
{
CreateCurrPath();
}
else if (datas.Count >= SaveRows)
{
//保存数据
Flush();
}
}
#endregion
public void Apply()
{
}
//获取历史数据
public void GetPaths(DateTime dt_begin, DateTime dt_end, string profilename,GetPathsReponseHandler return_func, object state)
{
List paths = GetPaths(dt_begin, dt_end, profilename);
return_func(paths,state);
}
List GetPaths(DateTime dt_begin, DateTime dt_end, string profilename)
{
List paths = new List();
Regex regex_file;
if (profilename != null)
{
string unescape = Regex.Escape(profilename);
regex_file = new Regex(@"\d{2}_\d{2}_\d{2}_.*" + unescape + @".*\.csv");
}
else
regex_file = new Regex(@"\d{2}_\d{2}_\d{2}.*\.csv");
for (int i = 0; i < dateInRootPath.Count(); i++)
{
if ((dateInRootPath[i].Date >= dt_begin.Date) && (dateInRootPath[i].Date <= dt_end.Date))
{
DateTime dt = dateInRootPath[i].Date;
string dirpath = RootPath + @"\" + dt.ToString(@"yyyy\\MM\\dd");
DirectoryInfo mydir = new DirectoryInfo(dirpath);
FileSystemInfo[] fsil_file = mydir.GetFileSystemInfos();
for (int j = 0; j < fsil_file.Count(); j++)
{
FileSystemInfo fsi = fsil_file[j];
if((fsi.Attributes != FileAttributes.Directory) && (regex_file.IsMatch(fsi.Name)))
{
paths.Add(dirpath + @"\" + fsi.Name);
}
}
//var fsil_file = from fsi in mydir.GetFileSystemInfos()
// where (fsi.Attributes == FileAttributes.Normal) && (regex_file.IsMatch(fsi.Name))
// select fsi;
//foreach (FileSystemInfo fsi in fsil_file)
//{
// paths.Add(dirpath + @"\" + fsi.Name);
//}
}
else if (dateInRootPath[i].Date > dt_end.Date)
{
break;
}
}
return paths;
}
public void GetRootPath(GetRootPathReponseHandler return_func, object state)
{
string path = System.Environment.CurrentDirectory;
return_func(path, state);
}
#region 自动删数据
private void InitKeepDay()
{
dateInRootPath.Clear();
if (!Directory.Exists(RootPath))
{
Directory.CreateDirectory(RootPath);
return;
}
DirectoryInfo mydir = new DirectoryInfo(RootPath);
//年
Regex regex_year = new Regex(@"\d{4}");
Regex regex_month = new Regex(@"\d{2}");
Regex regex_day = new Regex(@"\d{2}");
var fsil_year = from fsi in mydir.GetFileSystemInfos()
where (fsi.Attributes == FileAttributes.Directory) && (regex_year.IsMatch(fsi.Name))
select fsi;
foreach (var fsi_year in fsil_year)
{
var fsil_month =
from fsi in ((DirectoryInfo)fsi_year).GetFileSystemInfos()
where (fsi.Attributes == FileAttributes.Directory) && (regex_month.IsMatch(fsi.Name))
select fsi;
foreach (var fsi_month in fsil_month)
{
var fsil_day =
from fsi in ((DirectoryInfo)fsi_month).GetFileSystemInfos()
where (fsi.Attributes == FileAttributes.Directory) && (regex_day.IsMatch(fsi.Name))
select fsi;
foreach (var fsi_day in fsil_day)
{
DateTime dt = new DateTime(
int.Parse(fsi_year.Name),
int.Parse(fsi_month.Name),
int.Parse(fsi_day.Name));
//if (DateTime.TryParse(fsi_year.Name.ToString() + "-" + fsi_month.Name.ToString() + "-" + fsi_day.Name.ToString(), out dt))
{
dateInRootPath.Add(dt);
}
}
}
}
dateInRootPath.Sort(new Comparison(
delegate(DateTime t1, DateTime t2)
{
if (t1 > t2)
return 1;
else if (t1 == t2)
return 0;
else
return -1;
}));
CurrDays = dateInRootPath.Count;
Keep();
}
private void Keep()
{
while (dateInRootPath.Count > KeeyDay)
{
string dirpath = RootPath+@"\"+dateInRootPath.First().ToString(@"yyyy\\MM\\dd");
Directory.Delete(dirpath,true);
dateInRootPath.RemoveAt(0);
}
CurrDays = dateInRootPath.Count;
}
private void Keep(DateTime dt)
{
if (dateInRootPath.Count() > 0)
{
DateTime last = dateInRootPath.Last();
if (last.Date == dt.Date)
return;
}
dateInRootPath.Add(dt.Date);
Keep();
}
#endregion
#region INotifyPropertyChanged 成员
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyname)
{
if(PropertyChanged!=null)
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
#endregion
}
}