using System.Collections.Generic; using System; using System.Drawing; using System.Diagnostics; using System.Data; using System.Collections; using System.Windows.Forms; using System.IO; using System.Text; using AR; using System.Reflection; namespace vmsnet { public class CFDB { // ..\Database\volt /* 전압 */ string _BaseDir; System.Text.StringBuilder[] StrBuf; ////데이터버퍼 DateTime[] LastTime; ////데이터시간 System.IO.FileInfo[] File; ////데이터파일정보 int MaxCount = 10; public bool IsReady { get; private set; } public CFDB(params string[] dirarrays) { var dir = System.IO.Path.Combine(dirarrays); _BaseDir = dir; StrBuf = new System.Text.StringBuilder[MaxCount]; LastTime = new DateTime[MaxCount]; File = new System.IO.FileInfo[MaxCount]; if (System.IO.Directory.Exists(_BaseDir) == false) { try { System.IO.Directory.CreateDirectory(_BaseDir); IsReady = true; } catch { IsReady = false; } } else IsReady = true; ////Data Initialize for (int i = 0; i < MaxCount; i++) { StrBuf[i] = new System.Text.StringBuilder(); LastTime[i] = DateTime.Now; File[i] = null; } } ////지정한 기간내 파일의 존재여부를 확인합니다. //public int GetfileCount(string table, DateTime sd, DateTime ed) //{ // return GetfileS(table, sd, ed).Count; //} /// /// 데이터를 기록합니다. /// /// 기록시간(파일명이 결정됨) /// 기록할테이블명(파일명) /// 기록할데이터(열데이터가 틀려서 고정할 수 없다) /// /// public bool InsertData(DateTime time, string table, StringBuilder buffers) { // volt 파일생성 string DayStr = time.ToString("yyyyMMdd"); byte TableIndex = byte.Parse(table.Substring(5)); ////해당데이터의 시간과 파일정보를 기록 LastTime[TableIndex - 1] = time; // 파일명 : (time.Hour ).ToString("00") + "_" + table + ".txt" File[TableIndex - 1] = new System.IO.FileInfo(_BaseDir + "\\" + DayStr.Substring(0, 4) + "\\" + DayStr.Substring(4, 2) + "\\" + DayStr.Substring(6) + "\\" + (time.Hour ).ToString("00") + "_" + table + ".txt"); if (!File[TableIndex - 1].Directory.Exists) File[TableIndex - 1].Directory.Create(); ////각테이블별로 시작 열번호를 넣는다. int si = 1 + 160 * (TableIndex - 1); int ei = si + (160 - 1); ////파일이 없다면 제목줄을 생성해준다. if (!File[TableIndex - 1].Exists) { ////헤더를 추가해야한다. var Header = new System.Text.StringBuilder(); Header.Append("\t" + "TIME"); for (int j = si; j <= ei; j++) { Header.Append("\t" + "C" + j.ToString("000")); } //Header.Append(vbTab + "KA") Header.AppendLine(); ////제목줄을 한칸띄운다 // 파일에 헤더 쓰기 //File[TableIndex - 1].WriteText(Header); // 이전 단독모드 /* 작성자: 이재웅, 작성일: 2024-09-23, 작성내용: 접근모드를 공유모드로 전환 */ using (FileStream fs = new FileStream(File[TableIndex - 1].FullName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) using (StreamWriter writer = new StreamWriter(fs)) { writer.Write(Header.ToString()); } } StrBuf[TableIndex - 1].AppendLine("\t" + time.ToFileTime().ToString() + buffers.ToString()); ////4kb 단위로 파일을 기록한다. if (StrBuf[TableIndex - 1].Length > 4096) ////실제파일 기록은 ★5초마다★ 한다. { //File[TableIndex - 1].AppendText(StrBuf[TableIndex - 1]); // 이전은 단독모드 /* 작성자: 이재웅, 작성일: 2024-09-23, 작성내용: 접근모드를 공유모드로 전환 */ using (FileStream fs = new FileStream(File[TableIndex - 1].FullName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)) using (StreamWriter writer = new StreamWriter(fs)) { writer.Write(StrBuf[TableIndex - 1].ToString()); } StrBuf[TableIndex - 1].Clear(); } return true; } ~CFDB() { ////버퍼에 남아잇는 데이터를 기록한다. for (int i = 0; i < MaxCount; i++) { if (StrBuf[i].Length > 0) { try { using (var writer = new StreamWriter(File[i].FullName, true, System.Text.Encoding.Default)) writer.Write(StrBuf[i].ToString());// } catch { } } StrBuf[i].Clear(); } } /// /// 저장폴더내에 존재하는 날짜정보를 반환합니다. /// /// /// //public List GetDateList() //{ // List REtval = new List(); // System.IO.DirectoryInfo BDI = new System.IO.DirectoryInfo(_BaseDir); // foreach (System.IO.DirectoryInfo Fd_Year in BDI.GetDirectories()) // { // foreach (System.IO.DirectoryInfo FD_Mon in Fd_Year.GetDirectories()) // { // foreach (System.IO.DirectoryInfo Fd_Day in FD_Mon.GetDirectories()) // { // if (Fd_Day.GetFiles().Length > 0) // { // REtval.Add(Fd_Year.Name + FD_Mon.Name + Fd_Day.Name); // } // } // } // } // REtval.Sort(); // return REtval; //} //public enum eTableList //{ // DATAB1 = 1, // DATAB2 = 2, // DATAB3 = 3, // DATAB4 = 4, // DATAB5 = 5 //} /// /// 저장폴더내에 존재하는 날짜정보를 반환합니다. /// /// 찾고자하는테이블명(파일은 시_테이블명.txt로 되어있다. /// /// //public List GetDateList(eTableList tablename) //{ // List REtval = new List(); // System.IO.DirectoryInfo BDI = new System.IO.DirectoryInfo(_BaseDir); // foreach (System.IO.DirectoryInfo Fd_Year in BDI.GetDirectories()) // { // foreach (System.IO.DirectoryInfo FD_Mon in Fd_Year.GetDirectories()) // { // foreach (System.IO.DirectoryInfo Fd_Day in FD_Mon.GetDirectories()) // { // if (Fd_Day.GetFiles("*_" + tablename.ToString() +".txt").Length > 0) // { // REtval.Add(Fd_Year.Name + FD_Mon.Name + Fd_Day.Name); // } // } // } // } // REtval.Sort(); // return REtval; //} public List<(int Year, int Month)> GetAvailableDates() { var availableDates = new List<(int Year, int Month)>(); if (!Directory.Exists(_BaseDir)) return availableDates; // Get all year directories foreach (var yearDir in Directory.GetDirectories(_BaseDir)) { if (int.TryParse(Path.GetFileName(yearDir), out int year)) { // Get all month directories within the year directory foreach (var monthDir in Directory.GetDirectories(yearDir)) { if (int.TryParse(Path.GetFileName(monthDir), out int month)) { availableDates.Add((year, month)); } } } } return availableDates; } ////기간내 존재하는 파일을 반환합니다(테이블단위) public List GetfileS(string table, DateTime sd, DateTime ed) { List REtval = new List(); int SttYear = sd.Year; int EndYear = ed.Year; if (EndYear < SttYear) return REtval; int SttMonth = sd.Month; int EndMonth = ed.Month; int SttDay = sd.Day; int EndDay = ed.Day; int si = int.Parse(sd.ToString("yyyyMMdd")); int ei = int.Parse(ed.ToString("yyyyMMdd")); bool SameDay = si == ei ? true : false; //for (int dayinfo = si; dayinfo <= ei; dayinfo++) //{ // string dayStr = dayinfo.ToString(); // string dirname = Path.Combine(_BaseDir, dayStr.Substring(0, 4), dayStr.Substring(4, 2), dayStr.Substring(6)); // var dir = new DirectoryInfo(dirname); // if (!dir.Exists) continue; // int startHour = (dayinfo == si) ? int.Parse(sd.ToString("HH")) : 0; // int endHour = (dayinfo == ei) ? int.Parse(ed.ToString("HH")) : 23; // // 동일 날짜인 경우 // if (SameDay) // { // startHour = int.Parse(sd.ToString("HH")); // endHour = int.Parse(ed.ToString("HH")); // } // for (int hourinfo = startHour; hourinfo <= endHour; hourinfo++) // { // string filename = Path.Combine(dir.FullName, $"{hourinfo:00}_{table}.txt"); // if (System.IO.File.Exists(filename)) // { // REtval.Add(filename); // } // } //} ////20140101 for (int dayinfo = si; dayinfo <= ei; dayinfo++) { string DayStr = dayinfo.ToString(); var dirname = Path.Combine(_BaseDir, DayStr.Substring(0, 4), DayStr.Substring(4, 2), DayStr.Substring(6)); var dir = new System.IO.DirectoryInfo(dirname); if (!dir.Exists) continue; ////폴더가 존재하므로 해당 테이블파일이 존재하는지 확인한다 if (SameDay) { ////동일날짜라면 해당 시간대만 조회하면됨 for (int hourinfo = int.Parse(sd.ToString("HH")); hourinfo <= int.Parse(ed.ToString("HH")); hourinfo++) { string fn = dir.FullName + "\\" + (hourinfo).ToString("00") + "_" + table + ".txt"; if (System.IO.File.Exists(fn)) REtval.Add(fn); } } else { if (dayinfo == si) ////시작일이라면 시작시간부터 24시까지 이다. { for (int hourinfo = int.Parse(sd.ToString("HH")); hourinfo <= 23; hourinfo++) { string fn = dir.FullName + "\\" + (hourinfo).ToString("00") + "_" + table + ".txt"; if (System.IO.File.Exists(fn)) REtval.Add(fn); } } else if (dayinfo == ei) ////종료일이라면 1~ 종료시까지이다. { for (int hourinfo = 0; hourinfo <= int.Parse(ed.ToString("HH")); hourinfo++) { string fn = dir.FullName + "\\" + (hourinfo).ToString("00") + "_" + table + ".txt"; if (System.IO.File.Exists(fn)) REtval.Add(fn); } } else { ////중간에 끼어있는 날짜라면 1~24모두가 속한다. for (int hourinfo = 0; hourinfo <= 23; hourinfo++) { string fn = dir.FullName + "\\" + (hourinfo).ToString("00") + "_" + table + ".txt"; if (System.IO.File.Exists(fn)) REtval.Add(fn); } } } } REtval.Sort(); return REtval; } } }