using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Globalization; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using Microsoft.Win32; using System.Threading; using System.Reflection.Emit; using System.Collections.ObjectModel; using static System.Windows.Forms.VisualStyles.VisualStyleElement.ProgressBar; using System.Diagnostics; using System.IO.MemoryMappedFiles; namespace Dat2Bin { public partial class Dat2BinForm : Form { int erro = 5; int headSize = 2048; float sps_pers = 1000.0f;//每秒采样点个数 1k 32k 16k int chNum = 1;//通道数 int databits = 4;//24位 3字节 DateTime beginTime, endTime; DateTime systemTime; int sysCnt = 0; string saveBinPath = "\\bin"; string saveDatPath = "\\splitdat"; int binHeadSize = 96; //原始数据文件链表 public LinkList DataList = new LinkList(); Dictionary pointStaNum = new Dictionary(); bool useBackGround = false; public BackgroundWorker bgwConvert; public List StationList { get; set; } public Dat2BinForm() { InitializeComponent(); systemTime = new DateTime(2023, 5, 1); InitControl(); } private void InitControl() { RegistryKey hklm = Registry.CurrentUser; //声明一个变量 RegistryKey hksw = hklm.OpenSubKey(@"SOFTWARE\Microsoft", true); //string sk = "Software\\Microsoft\\ms"; RegistryKey hksm = hksw.OpenSubKey("ms", true); //RegistryKey cn; if (hksm == null) { hksw.CreateSubKey("ms"); hksm = hksw.OpenSubKey("ms", true); hksm.SetValue("cnt", "0"); hksm.SetValue("cd", DateTime.Now.ToString()); } sysCnt = int.Parse(hksm.GetValue("cnt").ToString()); hksm.SetValue("cnt", (sysCnt + 1).ToString()); systemTime = DateTime.Parse(hksm.GetValue("cd").ToString()); //Console.WriteLine(systemTime.ToString()); if (hklm != null) { hklm.Close(); } if (hksw != null) { hksw.Close(); } if (hksm != null) { hksm.Close(); } } private void buttonSelectData_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Multiselect = true; //saveFileDialog1.Filter = "JPeg Image|*.jpg|Bitmap Image|*.bmp|Gif Image|*.gif"; ofd.Filter = "Dat数据(*.dat) |*.dat"; ofd.Title = "Open an Data File"; if (ofd.ShowDialog() == DialogResult.OK) { //只读取Z分量数据 //string[] fns = Directory.GetFiles(Path.GetDirectoryName(ofd.FileName), "*.dat"); //string[] fnsZ = fns.Where(fn => fn.Contains("ch01")).ToArray(); //savePath = Path.GetDirectoryName(ofd.FileName) + "\\bin"; //if (!Directory.Exists(savePath)) //{ // Directory.CreateDirectory(savePath); //} //OpenDataFile(fnsZ); //listView1.Items.Clear(); //AddSourceDataFileToMyListView(); //读取所有数据 string[] fns = Directory.GetFiles(Path.GetDirectoryName(ofd.FileName), "*.dat"); //string[] fnsZ = fns.Where(fn => fn.Contains("ch01")).ToArray(); saveBinPath = Path.GetDirectoryName(ofd.FileName) + "\\bin"; if (!Directory.Exists(saveBinPath)) { Directory.CreateDirectory(saveBinPath); } saveDatPath = Path.GetDirectoryName(ofd.FileName) + "\\splitdat"; if (!Directory.Exists(saveDatPath)) { Directory.CreateDirectory(saveDatPath); } OpenDataFile(fns); listView1.Items.Clear(); AddSourceDataFileToMyListView(); } } private void OpenDataFile(string[] FileNames) { //try { //清除原来的链表 DataList.Clear(); byte[] temp = new byte[headSize]; bool isExist = false; for (int i = 0; i < FileNames.Length; i++) { string fn = Path.GetFileName(FileNames[i]); string channel = Path.GetFileNameWithoutExtension(fn).Substring(5, 4); /*如果文件名已经存在则不添加*/ for (int k = 1; k <= DataList.Length; k++) { if (DataList.GetnodeData(k).fileName == FileNames[i]) { isExist = true; } } if (isExist) { isExist = false; continue; } //以文件的全路对应的字符串和文件打开模式来初始化FileStream文件流实例 FileStream OldDataFileStream = new FileStream(FileNames[i], FileMode.Open); //以FileStream文件流来初始化BinaryReader文件阅读器 BinaryReader OldDataReadLineSReader = new BinaryReader(OldDataFileStream); if (OldDataFileStream.Length <= headSize) { MessageBox.Show(fn + "数据文件大小不够"); } else { OldDataReadLineSReader.Read(temp, 0, headSize); // readLineSReader.Read() HEADInfo OldDataFileHead = (HEADInfo)BytesToStuct(temp, typeof(HEADInfo)); OldDataFileHead.standby8 = channel; if (OldDataFileHead.year < 2000) { OldDataFileHead.year += 2000; } DateTime fileStartTime = new DateTime(OldDataFileHead.year, OldDataFileHead.month, OldDataFileHead.day, OldDataFileHead.hour, OldDataFileHead.minute, OldDataFileHead.sec); //UTC时间TO北京时间 fileStartTime = fileStartTime.AddHours(8);//截取电流时候用 sps_pers = Convert.ToSingle(textBox_sps.Text); //根据数据量计算和采样率计算采集时长 //文件头 2个通道 每个数据4个字节 long timesec = (OldDataFileStream.Length - headSize) / chNum / databits / (int)sps_pers; DateTime fileEndTime = fileStartTime.AddSeconds(timesec); // DateTime fileEndTime = fileStartTime.AddSeconds(timesec+1);//截取电流 DataList.Add(FileNames[i], fn, fileStartTime, fileEndTime, OldDataFileHead); } OldDataReadLineSReader.Close(); OldDataFileStream.Close(); } } //catch (Exception ex) //{ // MessageBox.Show(ex.ToString()); //} } public void AddSourceDataFileToMyListView() { if (DataList.Length <= 0) { return; } try { ListViewItem[] boxitems = new ListViewItem[DataList.Length]; for (int i = 0; i < DataList.Length; i++) { SiteParameter OldDateFiledata = DataList.GetnodeData(i + 1); boxitems[i] = new ListViewItem(); boxitems[i].Text = Convert.ToString(i + 1); boxitems[i].SubItems.Add(OldDateFiledata.SafeFileName.ToString()); boxitems[i].SubItems.Add(OldDateFiledata.fileStartTime.ToString("yyyy-MM-dd H:mm:ss", new CultureInfo("zh-CHS"))); boxitems[i].SubItems.Add(OldDateFiledata.fileEndTime.ToString("yyyy-MM-dd H:mm:ss", new CultureInfo("zh-CHS"))); } DateTime maxStartTime = DataList.GetnodeData(1).fileStartTime; DateTime minEndTime = DataList.GetnodeData(1).fileEndTime; for (int i = 1; i < DataList.Length; i++) { if (DataList.GetnodeData(i).fileStartTime > maxStartTime) { maxStartTime = DataList.GetnodeData(i).fileStartTime; } if (DataList.GetnodeData(i).fileEndTime < minEndTime) { minEndTime = DataList.GetnodeData(i).fileEndTime; } } dtpBeginTime.Value = maxStartTime; dtpEndTime.Value = minEndTime; listView1.Items.AddRange(boxitems); } catch (System.Exception ex) { Console.WriteLine(ex); } } private void MyListView1Clear() { //清除原来的链表 DataList.Clear(); listView1.Items.Clear(); } public static byte[] StructToBytes(object structObj, int size)//对于TCP包需要直接指定大小 { //得到结构体的大小 //int size = Marshal.SizeOf(structObj); //创建byte数组 byte[] bytes = new byte[size]; //分配结构体大小的内存空间 IntPtr structPtr = Marshal.AllocHGlobal(size); //将结构体拷到分配好的内存空间 Marshal.StructureToPtr(structObj, structPtr, false); //从内存空间拷到byte数组 Marshal.Copy(structPtr, bytes, 0, size); //释放内存空间 Marshal.FreeHGlobal(structPtr); //返回byte数组 return bytes; } public static object BytesToStuct(byte[] bytes, Type type) { //得到结构体的大小 int size = Marshal.SizeOf(type); //byte数组长度小于结构体的大小 if (size > bytes.Length) { //返回空 return null; } //分配结构体大小的内存空间 IntPtr structPtr = Marshal.AllocHGlobal(size); //将byte数组拷到分配好的内存空间 Marshal.Copy(bytes, 0, structPtr, size); //将内存空间转换为目标结构体 object obj = Marshal.PtrToStructure(structPtr, type); //释放内存空间 Marshal.FreeHGlobal(structPtr); //返回结构体 return obj; } private void Form1_Load(object sender, EventArgs e) { //int temp1 = 0x05;//0B00000101 //int temp2 = 0x09;//0B00001001 //int checkBit3 = 0x04;//0B0000100 提取第三位 //int checkBit8 = 0x08;//0B0000100 提取第四位 //int result3 = temp1 & checkBit3; //int result4 = temp2 & checkBit8; //Console.WriteLine(result3); //Console.WriteLine(result4); cbUseBackGround.Checked = useBackGround; this.Text = "DatToBin_20201015"; SetMyListView1(); } private void SetMyListView1() { //double v = 3.5; //double m = v % 1; //Console.WriteLine(m.ToString()); // Set the view to show details. listView1.View = View.Details; // Allow the user to edit item text. listView1.LabelEdit = false; // Allow the user to rearrange columns. listView1.AllowColumnReorder = true; // Display check boxes. listView1.CheckBoxes = false; // Select the item and subitems when selection is made. listView1.FullRowSelect = true; // Display grid lines. listView1.GridLines = true; int width = 200; listView1.Columns.Add("编号", 50, HorizontalAlignment.Center); listView1.Columns.Add("文件名称", 300, HorizontalAlignment.Center); listView1.Columns.Add("开始采集时间", width, HorizontalAlignment.Center); listView1.Columns.Add("结束采集时间", width, HorizontalAlignment.Center); // listView1.Columns.Add("采样速率", 150, HorizontalAlignment.Center); listView1.Visible = true; listView1.Font = new System.Drawing.Font("Arial", 12); } private void buttonReadStaNum_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Multiselect = true; ofd.Filter = "台站编号(*.txt) |*.txt"; ofd.Title = "Open a Text File"; if (ofd.ShowDialog() == DialogResult.OK) { pointStaNum = new Dictionary(); StreamReader sr = new StreamReader(ofd.FileName, Encoding.Default); while (sr.Peek() >= 0) { string[] strs = sr.ReadLine().Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries); pointStaNum.Add(int.Parse(strs[0]), int.Parse(strs[1])); } //listBox1.Items.AddRange(pointStaNum); foreach (var item in pointStaNum) { listBox1.Items.Add(item.Key + "\t" + item.Value); } } } private void buttonConvertBin_Click(object sender, EventArgs e) { if (useBackGround) { bgwConvert = new BackgroundWorker(); bgwConvert.DoWork += BgwConvert_DoWork; bgwConvert.ProgressChanged += BgwConvert_ProgressChanged; bgwConvert.RunWorkerCompleted += BgwConvert_RunWorkerCompleted; bgwConvert.WorkerReportsProgress = true; bgwConvert.WorkerSupportsCancellation = true; pgbarPrecent.Value = 0; lblPrecent.Text = "0%"; bgwConvert.RunWorkerAsync(); } else { DatToBinConvert(null, null); } } private void BgwConvert_SplitDatRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled) { MessageBox.Show("您取消了操作!"); //pgbarPrecent.Value = 0; //lblPrecent.Text = "0%"; } else if (e.Error != null) { MessageBox.Show("出现错误!"); } else { MessageBox.Show("完成"); //pgbarPrecent.Value = 0; //lblPrecent.Text = "0%"; } } private void BgwConvert_SplitDatProgressChanged(object sender, ProgressChangedEventArgs e) { pgbarPrecent.Value = e.ProgressPercentage; lblPrecent.Text = (string)e.UserState + "%"; } private void BgwConvert_SplitDat(object sender, DoWorkEventArgs e) { SplitDatConvertAsync(sender, e); } public async void SplitDatConvertAsync(object sender, DoWorkEventArgs e) { beginTime = dtpBeginTime.Value; endTime = dtpEndTime.Value; ////单个文件时长 //int singleFileLength = int.Parse(textBoxSingleFileLength.Text) * 60; // 截取时长 int splitLength = (int)(endTime - beginTime).TotalSeconds; if (((DateTime.Now - systemTime).TotalDays < 30) && ((DateTime.Now - systemTime).TotalDays >= 0) && sysCnt < 90) { List nodeList = new List(); //创建并启动计时器 Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); for (int dli = 0; dli < DataList.Length; dli++) { SiteParameter nodeData = this.DataList.GetnodeData(dli + 1); nodeList.Add(nodeData); //await ProcessFilesAsync(nodeData, beginTime, splitLength); // WriteDatFile(nodeData, beginTime, splitLength); //Task task=WriteDatFileTask(nodeData, beginTime, splitLength); //task.Start(); //tasks.Add(task); //WriteDatFileAsync(nodeData, beginTime, splitLength); //task.Start(); } await ProcessFilesAsync(nodeList, beginTime, splitLength); stopwatch.Stop(); TimeSpan elapsedTime = stopwatch.Elapsed; // 打印执行时间 Console.WriteLine($"异步分割时长: {elapsedTime.TotalMilliseconds}ms"); nodeList = null; MessageBox.Show("转换完成"); } else { MessageBox.Show("数据格式错误!"); } } public async Task WriteDatFileAsync(SiteParameter nodeData, DateTime startTime, int secs) { if (secs <= 0) { throw new ArgumentException("Parameter secs must be a positive integer."); } FileInfo fileInfo = new FileInfo(nodeData.fileName); int count = secs * 4000; if (fileInfo.Length >= (count + 2048)) { DateTime dt = startTime.AddHours(-8); string fileName = BuildNewFileName(nodeData, dt); try { using (FileStream input = new FileStream(nodeData.fileName, FileMode.Open)) using (BinaryReader reader = new BinaryReader(input)) using (FileStream saveFileStream = new FileStream(saveDatPath + "\\" + fileName, FileMode.Create)) using (BinaryWriter writeLineSReader = new BinaryWriter(saveFileStream)) { WriteFileHeader(writeLineSReader, nodeData, dt); await WriteFileDataAsync(input, reader, writeLineSReader, startTime, nodeData, count); } } catch (Exception ex) { // Log the exception or show an error message to the user. Console.WriteLine($"Error: {ex.Message}"); } } } private void WriteFileHeader(BinaryWriter writer, SiteParameter nodeData, DateTime dt) { nodeData.fileHead.year = (short)dt.Year; nodeData.fileHead.month = (short)dt.Month; nodeData.fileHead.day = (short)dt.Day; nodeData.fileHead.hour = (short)(dt.Hour); nodeData.fileHead.minute = (short)dt.Minute; nodeData.fileHead.sec = (byte)dt.Second; byte[] hs = StructToBytes(nodeData.fileHead, this.headSize); writer.Write(hs); } private async Task WriteFileDataAsync(FileStream input, BinaryReader reader, BinaryWriter writer, DateTime startTime, SiteParameter nodeData, int count) { byte[] buffer = new byte[count]; int seekOff = (int)((startTime - nodeData.fileStartTime).TotalSeconds) * 4000; input.Seek((long)this.headSize + seekOff, SeekOrigin.Begin); reader.Read(buffer, 0, count); await writer.BaseStream.WriteAsync(buffer, 0, count); } public async Task ProcessFilesAsync(List nodeDataList, DateTime startTime, int secs) { List tasks = new List(); foreach (SiteParameter nodeData in nodeDataList) { Task task = WriteDatFileAsync(nodeData, startTime, secs); tasks.Add(task); } await Task.WhenAll(tasks); } public void WriteDatFile(SiteParameter nodeData, DateTime startTime, int secs) { if (secs <= 0) { throw new ArgumentException("Parameter secs must be a positive integer."); } FileInfo fileInfo = new FileInfo(nodeData.fileName); int count = secs * 4000; if (fileInfo.Length >= (count + 2048)) { DateTime dt = startTime.AddHours(-8); string fileName = BuildNewFileName(nodeData, dt); try { using (FileStream input = new FileStream(nodeData.fileName, FileMode.Open)) using (BinaryReader reader = new BinaryReader(input)) using (FileStream saveFileStream = new FileStream(saveDatPath + "\\" + fileName, FileMode.Create)) using (BinaryWriter writeLineSReader = new BinaryWriter(saveFileStream)) { WriteFileHeader(writeLineSReader, nodeData, dt); WriteFileData(input, reader, writeLineSReader, startTime, nodeData, count); } } catch (Exception ex) { // Log the exception or show an error message to the user. Console.WriteLine($"Error: {ex.Message}"); } } } private string BuildNewFileName(SiteParameter nodeData, DateTime dt) { return nodeData.SafeFileName.Substring(0, 10) + dt.Year.ToString("0000") + dt.Month.ToString("00") + dt.Day.ToString("00") + "_" + dt.Hour.ToString("00") + dt.Minute.ToString("00") + dt.Second.ToString("00") + ".dat"; } private void WriteFileData(FileStream input, BinaryReader reader, BinaryWriter writer, DateTime startTime, SiteParameter nodeData, int count) { byte[] buffer = new byte[count]; int seekOff = (int)((startTime - nodeData.fileStartTime).TotalSeconds) * 4000; input.Seek((long)this.headSize + seekOff, SeekOrigin.Begin); reader.Read(buffer, 0, count); writer.Write(buffer); } public Task WriteDatFileTask(SiteParameter nodeData, DateTime startTime, int secs) { FileInfo fileInfo = new FileInfo(nodeData.fileName); int count = secs * 4000; Task task = null; if (fileInfo.Length >= (count + 2048)) { task = new Task(() => { DateTime dt = startTime.AddHours(-8); string fileName = nodeData.SafeFileName.Substring(0, 10) + dt.Year.ToString("0000") + dt.Month.ToString("00") + dt.Day.ToString("00") + "_" + dt.Hour.ToString("00") + dt.Minute.ToString("00") + dt.Second.ToString("00") + ".dat"; FileStream input = new FileStream(nodeData.fileName, FileMode.Open); BinaryReader reader = new BinaryReader(input); FileStream SaveFileStream = new FileStream(saveDatPath + "\\" + fileName, FileMode.Create); BinaryWriter WriteLineSReader = new BinaryWriter(SaveFileStream); nodeData.fileHead.year = (short)dt.Year; nodeData.fileHead.month = (short)dt.Month; nodeData.fileHead.day = (short)dt.Day; nodeData.fileHead.hour = (short)(dt.Hour); nodeData.fileHead.minute = (short)dt.Minute; nodeData.fileHead.sec = (byte)dt.Second; byte[] hs = StructToBytes(nodeData.fileHead, this.headSize); WriteLineSReader.Write(hs); byte[] buffer = new byte[count]; int seekOff = (int)((startTime - nodeData.fileStartTime).TotalSeconds) * 4000; input.Seek((long)this.headSize + seekOff, SeekOrigin.Begin); reader.Read(buffer, 0, count); WriteLineSReader.Write(buffer); input.Close(); reader.Close(); SaveFileStream.Close(); WriteLineSReader.Close(); }); } return task; } public void WriteDatFileTay(SiteParameter nodeData, DateTime startTime, int secs) { FileInfo fileInfo = new FileInfo(nodeData.fileName); int count = secs * 4000; if (fileInfo.Length >= (count + 2048)) { DateTime dt = startTime.AddHours(-8); string fileName = nodeData.SafeFileName.Substring(0, 10) + dt.Year.ToString("0000") + dt.Month.ToString("00") + dt.Day.ToString("00") + "_" + dt.Hour.ToString("00") + dt.Minute.ToString("00") + dt.Second.ToString("00") + ".dat"; FileStream input = new FileStream(nodeData.fileName, FileMode.Open); BinaryReader reader = new BinaryReader(input); FileStream SaveFileStream = new FileStream(saveDatPath + "\\" + fileName, FileMode.Create); BinaryWriter WriteLineSReader = new BinaryWriter(SaveFileStream); nodeData.fileHead.year = (short)dt.Year; nodeData.fileHead.month = (short)dt.Month; nodeData.fileHead.day = (short)dt.Day; nodeData.fileHead.hour = (short)(dt.Hour); nodeData.fileHead.minute = (short)dt.Minute; nodeData.fileHead.sec = (byte)dt.Second; byte[] hs = StructToBytes(nodeData.fileHead, this.headSize); WriteLineSReader.Write(hs); byte[] buffer = new byte[count]; int seekOff = (int)((startTime - nodeData.fileStartTime).TotalSeconds) * 4000; input.Seek((long)this.headSize + seekOff, SeekOrigin.Begin); reader.Read(buffer, 0, count); WriteLineSReader.Write(buffer); input.Close(); reader.Close(); SaveFileStream.Close(); WriteLineSReader.Close(); } } public void WriteDatFileTestSpan(SiteParameter nodeData, DateTime startTime, int secs) { FileInfo fileInfo = new FileInfo(nodeData.fileName); int count = secs * 4000; if (fileInfo.Length >= (count + 2048)) { DateTime dt = startTime.AddHours(-8); string fileName = nodeData.SafeFileName.Substring(0, 10) + dt.Year.ToString("0000") + dt.Month.ToString("00") + dt.Day.ToString("00") + "_" + dt.Hour.ToString("00") + dt.Minute.ToString("00") + dt.Second.ToString("00") + ".dat"; FileStream input = new FileStream(nodeData.fileName, FileMode.Open); BinaryReader reader = new BinaryReader(input); FileStream SaveFileStream = new FileStream(saveDatPath + "\\" + fileName, FileMode.Create); BinaryWriter WriteLineSReader = new BinaryWriter(SaveFileStream); nodeData.fileHead.year = (short)dt.Year; nodeData.fileHead.month = (short)dt.Month; nodeData.fileHead.day = (short)dt.Day; nodeData.fileHead.hour = (short)(dt.Hour); nodeData.fileHead.minute = (short)dt.Minute; nodeData.fileHead.sec = (byte)dt.Second; byte[] hs = StructToBytes(nodeData.fileHead, this.headSize); //Stopwatch sw = Stopwatch.StartNew(); WriteLineSReader.Write(hs); //sw.Stop(); //Console.WriteLine($"写入头的时长:{sw.ElapsedMilliseconds}"); /*sw.Start()*/; byte[] buffer = new byte[count]; int seekOff = (int)((startTime - nodeData.fileStartTime).TotalSeconds) * 4000; input.Seek((long)this.headSize + seekOff, SeekOrigin.Begin); reader.Read(buffer, 0, count); //sw.Stop(); //Console.WriteLine($"读取数据的时长:{sw.ElapsedMilliseconds}"); //sw.Start(); WriteLineSReader.Write(buffer); //sw.Stop(); //Console.WriteLine($"运行时长:{sw.ElapsedMilliseconds}ms"); input.Close(); reader.Close(); SaveFileStream.Close(); WriteLineSReader.Close(); } } public async Task WriteDatFileAsyncIO(SiteParameter nodeData, DateTime startTime, int secs) { FileInfo fileInfo = new FileInfo(nodeData.fileName); long count = secs * 4000L; if (fileInfo.Length >= (count + 2048)) { DateTime dt = startTime.AddHours(-8); string fileName = nodeData.SafeFileName.Substring(0, 10) + dt.Year.ToString("0000") + dt.Month.ToString("00") + dt.Day.ToString("00") + "_" + dt.Hour.ToString("00") + dt.Minute.ToString("00") + dt.Second.ToString("00") + ".dat"; using (FileStream inputFileStream = new FileStream(nodeData.fileName, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 4096, useAsync: true)) { using (FileStream SaveFileStream = new FileStream(saveDatPath + "\\" + fileName, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true)) { // 写入文件头 nodeData.fileHead.year = (short)dt.Year; nodeData.fileHead.month = (short)dt.Month; nodeData.fileHead.day = (short)dt.Day; nodeData.fileHead.hour = (short)(dt.Hour); nodeData.fileHead.minute = (short)dt.Minute; nodeData.fileHead.sec = (byte)dt.Second; byte[] hs = StructToBytes(nodeData.fileHead, this.headSize); await SaveFileStream.WriteAsync(hs, 0, hs.Length); // 读取数据并写入新文件 int seekOff = (int)((startTime - nodeData.fileStartTime).TotalSeconds) * 4000; long offset = this.headSize + seekOff * sizeof(float); long bytesToRead = count * sizeof(float); long totalBytesRead = 0; int bufferSize = 1024 * 1024; // 1MB buffer byte[] buffer = new byte[bufferSize]; while (bytesToRead > 0) { int bytesRead = (int)Math.Min(bufferSize, bytesToRead); int numBytesRead = await inputFileStream.ReadAsync(buffer, 0, bytesRead); if (numBytesRead == 0) { break; } totalBytesRead += numBytesRead; bytesToRead -= numBytesRead; await SaveFileStream.WriteAsync(buffer, 0, numBytesRead); } } } } } public void WriteDatFileAsync2(SiteParameter nodeData, DateTime startTime, int secs) { FileInfo fileInfo = new FileInfo(nodeData.fileName); long count = secs * 4000L; if (fileInfo.Length >= (count + 2048)) { DateTime dt = startTime.AddHours(-8); string fileName = nodeData.SafeFileName.Substring(0, 10) + dt.Year.ToString("0000") + dt.Month.ToString("00") + dt.Day.ToString("00") + "_" + dt.Hour.ToString("00") + dt.Minute.ToString("00") + dt.Second.ToString("00") + ".dat"; using (var mmf = MemoryMappedFile.CreateFromFile(nodeData.fileName, FileMode.Open)) { using (var accessor = mmf.CreateViewAccessor()) { using (FileStream SaveFileStream = new FileStream(saveDatPath + "\\" + fileName, FileMode.Create)) { using (BinaryWriter writer = new BinaryWriter(SaveFileStream)) { // 写入文件头 nodeData.fileHead.year = (short)dt.Year; nodeData.fileHead.month = (short)dt.Month; nodeData.fileHead.day = (short)dt.Day; nodeData.fileHead.hour = (short)(dt.Hour); nodeData.fileHead.minute = (short)dt.Minute; nodeData.fileHead.sec = (byte)dt.Second; byte[] hs = StructToBytes(nodeData.fileHead, this.headSize); writer.Write(hs); // 读取数据并写入新文件 int seekOff = (int)((startTime - nodeData.fileStartTime).TotalSeconds) * 4000; long offset = this.headSize + seekOff * sizeof(float); long bytesToRead = count * sizeof(float); long totalBytesRead = 0; int bufferSize = 1024 * 1024; // 1MB buffer byte[] buffer = new byte[bufferSize]; while (bytesToRead > 0) { int bytesRead = (int)Math.Min(bufferSize, bytesToRead); accessor.ReadArray(offset + totalBytesRead, buffer, 0, bytesRead); totalBytesRead += bytesRead; bytesToRead -= bytesRead; writer.Write(buffer, 0, bytesRead); } } } } } } } private void BgwConvert_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled) { MessageBox.Show("您取消了操作!"); //pgbarPrecent.Value = 0; //lblPrecent.Text = "0%"; } else if (e.Error != null) { MessageBox.Show("出现错误!"); } else { MessageBox.Show("完成"); //pgbarPrecent.Value = 0; //lblPrecent.Text = "0%"; } } private void BgwConvert_ProgressChanged(object sender, ProgressChangedEventArgs e) { pgbarPrecent.Value = e.ProgressPercentage; lblPrecent.Text = (string)e.UserState + "%"; } private void BgwConvert_DoWork(object sender, DoWorkEventArgs e) { DatToBinConvert(sender, e); MessageBox.Show("转换完成"); } public void DatToBinConvert(object sender, DoWorkEventArgs e) { beginTime = dtpBeginTime.Value; endTime = dtpEndTime.Value; DateTime CurTime; //读取数据时长 int totalSec = 0; //当前时差 int timeDiff = 0; //单个文件时长 int singleFileLength = int.Parse(textBoxSingleFileLength.Text) * 60; for (int dli = 0; dli < DataList.Length; dli++) { SiteParameter nodeData = this.DataList.GetnodeData(dli + 1); CurTime = beginTime; while (nodeData.fileEndTime >= CurTime && CurTime >= nodeData.fileStartTime) { if (CurTime > endTime) { break; } else { //计算文件结束时间与当前时间的时差 timeDiff = (int)(endTime - CurTime).TotalSeconds; //如果当前时差小于单个文件时长,当前时间增加当前时差,否则当前时间增加单个文件时长 if (timeDiff <= 0) { break; } else if (timeDiff < singleFileLength) { totalSec = timeDiff; } else { totalSec = singleFileLength; } //读取Dat数据,生成Bin文件 WriteBinData(nodeData, CurTime, totalSec); } if (useBackGround) { float precent = (dli + 1f) / ((float)DataList.Length) * 100f; bgwConvert.ReportProgress((int)precent, Math.Round(precent, 2).ToString()); } CurTime = CurTime.AddSeconds(totalSec); } } } private void cbUseBackGround_CheckedChanged(object sender, EventArgs e) { useBackGround = cbUseBackGround.Checked; } public void ReadByte(string fn) { FileStream input = new FileStream(fn, FileMode.Open); BinaryReader reader = new BinaryReader(input); input.Seek((long)this.headSize, SeekOrigin.Begin); byte[] buffer = new byte[4]; reader.Read(buffer, 0, 4); int intData = BitConverter.ToInt32(buffer, 0); //byte[] b2 = Int32ToBytes(intData); float f = (float)(intData * 0.000000000011641532f); byte[] b2 = FloatToBytes(f, false); Console.WriteLine("[0]:{0}\t[1]:{1}\t[2]:{2}\t[3]:{3}", b2[0], b2[1], b2[2], b2[3]); //Console.WriteLine("[0]:{0}\t[1]:{1}\t[2]:{2}\t[3]:{3}\tint:{4}\tfloat:{5}", buffer[0], buffer[1], buffer[2], buffer[3],intData, f); input.Close(); reader.Close(); } public void WriteBinData(SiteParameter nodeData, DateTime curTime, int totalSeconds) { HEADInfo info = (HEADInfo)BytesToStuct(StructToBytes(nodeData.fileHead, this.headSize), typeof(HEADInfo)); int staNum = int.Parse(info.Nst.ToString().Substring(2, 2)); int pointNum = staNum; if (pointStaNum.Count > 0) { var psnw = pointStaNum.Where(psn => psn.Value == staNum); if (psnw == null) { return; } if (psnw.Count() == 0) { return; } //var psnr = psnw.First(); //if (psnr.) //{ // return; //} pointNum = psnw.First().Key; } string fileName = "N" + String.Format("{0:d3}", pointNum) + "_" + curTime.Year.ToString("0000") + "-" + curTime.Month.ToString("00") + "-" + curTime.Day.ToString("00") + "~" + curTime.Hour.ToString("00") + "_" + String.Format("{0:d3}", 1) + ".bin"; FileStream input = new FileStream(nodeData.fileName, FileMode.Open); BinaryReader reader = new BinaryReader(input); FileStream SaveFileStream = new FileStream(saveBinPath + "\\" + fileName, FileMode.Create); BinaryWriter WriteLineSReader = new BinaryWriter(SaveFileStream); int count = (this.chNum * this.databits) * ((int)this.sps_pers); byte[] buffer = new byte[count]; char[] chars = new char[this.binHeadSize]; byte[] buffer3 = new byte[count]; int seekOff = (int)((curTime - nodeData.fileStartTime).TotalSeconds) * 4000; input.Seek((long)this.headSize + seekOff, SeekOrigin.Begin); for (int j = 0; j < totalSeconds; j++) { reader.Read(buffer, 0, count); for (int k = 0; k < count; k += 4) { //buffer3[k] = buffer[k + 3]; //buffer3[k + 1] = buffer[k + 2]; //buffer3[k + 2] = buffer[k + 1]; //buffer3[k + 3] = buffer[k ]; //if (buffer[k + 3] == 0) //{ // buffer3[k + 1] = 0xFF; //} //else //{ // buffer3[k + 1] = buffer[k + 3]; //} //buffer3[k + 2] = buffer[k + 2]; //buffer3[k + 3] = buffer[k + 1]; //buffer3[k] = buffer[k]; buffer3[k] = 0xFF; if (buffer[k + 3] == 0) { buffer3[k + 1] = 0xFF; } else { buffer3[k + 1] = buffer[k + 3]; } buffer3[k + 2] = buffer[k + 2]; buffer3[k + 3] = buffer[k + 1]; } DateTime time = curTime.AddSeconds((double)j); string[] strArray4 = new string[] { "$GPRMC,", time.Hour.ToString("00"), time.Minute.ToString("00"), time.Second.ToString("00"), ".00,A,", info.channel[0].Y.ToString("0000.00000"), ",N,", info.channel[0].X.ToString("00000.00000"), ",E,0.002,,", time.Day.ToString("00"), time.Month.ToString("00"), (time.Year - 0x7d0).ToString("00"), ",,,A*7\r\n" }; string str6 = string.Concat(strArray4); string[] strArray5 = new string[0x10]; strArray5[0] = "$$175B"; strArray5[1] = time.Year.ToString("0000"); strArray5[2] = "-"; strArray5[3] = time.Month.ToString("00"); strArray5[4] = "-"; strArray5[5] = time.Day.ToString("00"); strArray5[6] = " "; strArray5[7] = time.Hour.ToString("00"); strArray5[8] = ":"; strArray5[9] = time.Minute.ToString("00"); strArray5[10] = ":"; strArray5[11] = time.Second.ToString("00"); strArray5[12] = " "; strArray5[13] = (pointNum).ToString("00"); strArray5[14] = " "; strArray5[15] = str6; chars = string.Concat(strArray5).ToCharArray(); WriteLineSReader.Write(chars); WriteLineSReader.Write(buffer3); } input.Close(); reader.Close(); SaveFileStream.Close(); WriteLineSReader.Close(); } private void button1_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Multiselect = true; ofd.Filter = "Dat数据(*.dat) |*.dat"; ofd.Title = "Open an Data File"; if (ofd.ShowDialog() == DialogResult.OK) { ReadByte(ofd.FileName); } } private void button2_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Multiselect = true; ofd.Filter = "Dat数据(*.bin) |*.bin"; ofd.Title = "Open an Data File"; if (ofd.ShowDialog() == DialogResult.OK) { FileStream input = new FileStream(ofd.FileName, FileMode.Open); BinaryReader reader = new BinaryReader(input); input.Seek(96, SeekOrigin.Begin); byte[] buffer = new byte[4]; reader.Read(buffer, 0, 4); int intData = ByteToInt32(buffer); //string utmp = String.Join("", (BitConverter.ToString(buffer, 0)).Split('-')); //Int64 intData = (GetBaseNum(utmp)); float ff = -5.516708f; int dd = (int)(ff / 0.0000000000582f); byte[] b2 = Int32ToBytes(dd); float fd = (float)(intData * 2.5f / 4294967296f); //Console.WriteLine("byte:{0}\tint:{1}\tint:{2}", buffer, intData,fd); Console.WriteLine("[0]:{0}\t[1]:{1}\t[2]:{2}\t[3]:{3}", b2[0], b2[1], b2[2], b2[3]); //Console.WriteLine("[0]:{0}\t[1]:{1}\t[2]:{2}\t[3]:{3}\tint:{4}\tfloat:{5}", buffer[0], buffer[1], buffer[2], buffer[3], intData, fd); input.Close(); reader.Close(); } } public float BytesToFloat(byte[] tempbyte, bool isBigEnd) { float tempInput = 0f; char[] tempchar = new char[8]; MemoryStream membuff = new MemoryStream(4); BinaryWriter bin2mem = new BinaryWriter(membuff); byte[] tb = new byte[4]; BinaryReader mem2float = new BinaryReader(membuff); if (isBigEnd) { tb[3] = tempbyte[0]; tb[2] = tempbyte[1]; tb[1] = tempbyte[2]; tb[0] = tempbyte[3]; } else { tb = tempbyte; } bin2mem.Write(tb, 0, 4); membuff.Position = 0; tempInput = mem2float.ReadSingle(); return tempInput; } public byte[] FloatToBytes(float value, bool isBigEnd) { byte[] tempbyte = new byte[4]; byte[] rtnBytes = new byte[4]; MemoryStream membuff = new MemoryStream(4); BinaryWriter bin2mem = new BinaryWriter(membuff); membuff.Position = 0; bin2mem.Write(value); tempbyte = membuff.ToArray(); if (isBigEnd) { for (int i = 0; i < tempbyte.Length; i++) { rtnBytes[i] = tempbyte[3 - i]; } } else { rtnBytes = tempbyte; } return rtnBytes; } private int ByteToInt32(Byte[] arrByte) { //按两个字节一个整数解析,前一字节当做整数低位,后一字节当做整数高位,调用系统函数转化 Byte[] tmpBytes = new Byte[4] { arrByte[3], arrByte[2], arrByte[1], arrByte[0] }; return BitConverter.ToInt32(tmpBytes, 0); } public byte[] Int32ToBytes(int indata) { byte[] destByteArr = new byte[4]; destByteArr[0] = Convert.ToByte((indata & 0x000000FF)); destByteArr[1] = Convert.ToByte((indata & 0x0000FF00) >> 8); destByteArr[2] = Convert.ToByte((indata & 0x00FF0000) >> 16); destByteArr[3] = Convert.ToByte((indata & 0xFF000000) >> 24); return destByteArr; } int GetBaseNum(String sComplement) { Int64 iTmp = Convert.ToInt32(sComplement, 16); if (iTmp >= 0x80000000) { iTmp = ~(iTmp - 1); //MessageBox.Show("1"); //iTmp = 0x1000000000 - iTmp; } return (int)iTmp; } //byte数组变为 float数值 private static float ToFloat(byte[] data) { //undefined unsafe { //undefined float a = 0.0F; byte i; byte[] x = data; void* pf; fixed (byte* px = x) { //undefined pf = &a; for (i = 0; i < data.Length; i++) { //undefined *((byte*)pf + i) = *(px + i); } } return a; } } private void btnReadDatSingle_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Multiselect = true; //saveFileDialog1.Filter = "JPeg Image|*.jpg|Bitmap Image|*.bmp|Gif Image|*.gif"; ofd.Filter = "Dat数据(*.dat) |*.dat"; ofd.Title = "Open an Data File"; if (ofd.ShowDialog() == DialogResult.OK) { string[] fns = Directory.GetFiles(Path.GetDirectoryName(ofd.FileName), "*.dat"); string[] fnsZ = fns.Where(fn => fn.Contains("ch01")).ToArray(); saveBinPath = Path.GetDirectoryName(ofd.FileName) + "\\bin"; if (!Directory.Exists(saveBinPath)) { Directory.CreateDirectory(saveBinPath); } OpenDataFile(fnsZ); listView1.Items.Clear(); AddSourceDataFileToMyListView(); } } private void button3_Click(object sender, EventArgs e) { string str = textBox1.Text; int si = GetBaseNum(str); Console.WriteLine(si); double dv = si * 5.82E-10; textBoxFloat.Text = dv.ToString(); int li = (int)(dv / 5.82E-10); Console.WriteLine(li); byte[] bs = BitConverter.GetBytes(li); string strx2 = ""; foreach (var item in bs) { strx2 += item.ToString("X2"); Console.WriteLine(item.ToString("X2")); } textBoxConByFloat.Text = strx2; ////string[] strs = str.Split(new char[] { ' '}); //byte[] bytes = Convert.FromBase64String(str); ////byte[] byteArray = System.Text.Encoding.ASCII.GetBytes(str); ////string str2= BitConverter.ToString(byteArray); //string str2 = Convert.ToBase64String(bytes); ////int intData = BitConverter.ToInt32(bytes, 0); ////byte[] b2 = Int32ToBytes(intData); //// float f = (float)(intData * 0.000000000011641532f); //float ff = BytesToFloat(bytes, cbBigEnd.Checked); //textBoxFloat.Text = ff.ToString(); //Console.WriteLine(ff.ToString()); ////Console.WriteLine(str2); ////foreach (var item in byteArray) ////{ //// Console.WriteLine(item); ////} } private void button4_Click(object sender, EventArgs e) { byte[] bs = FloatToBytes(float.Parse(textBoxFloat.Text), cbBigEnd.Checked); string str = ""; for (int i = 0; i < bs.Length; i++) { str += bs[i].ToString("X2"); } textBoxConByFloat.Text = str; } private void buttonReadStaNum2_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Multiselect = true; ofd.Filter = "台站编号(*.spj) |*.spj"; ofd.Title = "Open a Text File"; if (ofd.ShowDialog() == DialogResult.OK) { pointStaNum = new Dictionary(); string[] rows = File.OpenText(ofd.FileName).ReadToEnd().Trim().Split('\n'); File.OpenText(ofd.FileName).Close(); int rowNum = 0; while (rowNum < rows.Length) { //台站信息 if (rows[rowNum].Contains("[台站信息]")) { int subNum = rowNum + 2; while (!rows[subNum].Contains("[井信息]")) { string[] cols = rows[subNum].Split('\t'); pointStaNum.Add(int.Parse(cols[0]), int.Parse(cols[1])); subNum++; } rowNum = subNum; continue; } rowNum++; } //listBox1.Items.AddRange(pointStaNum); listBox1.Items.Clear(); foreach (var item in pointStaNum) { listBox1.Items.Add(item.Key + "\t" + item.Value); } } } private void buttonSplitDat_Click(object sender, EventArgs e) { SplitDatConvert(null,null); } public void SplitDatConvert(object sender, DoWorkEventArgs e) { beginTime = dtpBeginTime.Value; endTime = dtpEndTime.Value; ////单个文件时长 //int singleFileLength = int.Parse(textBoxSingleFileLength.Text) * 60; // 截取时长 int splitLength = (int)(endTime - beginTime).TotalSeconds; if (((DateTime.Now - systemTime).TotalDays < 30) && ((DateTime.Now - systemTime).TotalDays >= 0) && sysCnt < 90) { List nodeList = new List(); //创建并启动计时器 Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); for (int dli = 0; dli < DataList.Length; dli++) { SiteParameter nodeData = this.DataList.GetnodeData(dli + 1); nodeList.Add(nodeData); //await ProcessFilesAsync(nodeData, beginTime, splitLength); WriteDatFile(nodeData, beginTime, splitLength); //Task task=WriteDatFileTask(nodeData, beginTime, splitLength); //task.Start(); //tasks.Add(task); //WriteDatFileAsync(nodeData, beginTime, splitLength); //task.Start(); } // await ProcessFilesAsync(nodeList, beginTime, splitLength); stopwatch.Stop(); TimeSpan elapsedTime = stopwatch.Elapsed; // 打印执行时间 Console.WriteLine($"同步分割时长: {elapsedTime.TotalMilliseconds}ms"); MessageBox.Show("转换完成"); } else { MessageBox.Show("数据格式错误!"); } } private void buttonSplitAsync_Click(object sender, EventArgs e) { if (useBackGround) { bgwConvert = new BackgroundWorker(); bgwConvert.DoWork += BgwConvert_SplitDat; bgwConvert.ProgressChanged += BgwConvert_SplitDatProgressChanged; bgwConvert.RunWorkerCompleted += BgwConvert_SplitDatRunWorkerCompleted; ; bgwConvert.WorkerReportsProgress = true; bgwConvert.WorkerSupportsCancellation = true; pgbarPrecent.Value = 0; lblPrecent.Text = "0%"; bgwConvert.RunWorkerAsync(); } else { SplitDatConvertAsync(null, null); } } public void WriteBinDataBak20201212(SiteParameter nodeData, DateTime curTime, int totalSeconds) { HEADInfo info = (HEADInfo)BytesToStuct(StructToBytes(nodeData.fileHead, this.headSize), typeof(HEADInfo)); int staNum = int.Parse(info.Nst.ToString().Substring(2, 2)); int pointNum = staNum; if (pointStaNum.Count > 0) { pointNum = (pointStaNum.First(psn => psn.Value == staNum).Key); } string fileName = "N" + String.Format("{0:d3}", pointNum) + "_" + curTime.Year.ToString("0000") + "-" + curTime.Month.ToString("00") + "-" + curTime.Day.ToString("00") + "~" + curTime.Hour.ToString("00") + "_" + String.Format("{0:d3}", 1) + ".bin"; FileStream input = new FileStream(nodeData.fileName, FileMode.Open); BinaryReader reader = new BinaryReader(input); FileStream SaveFileStream = new FileStream(saveBinPath + "\\" + fileName, FileMode.Create); BinaryWriter WriteLineSReader = new BinaryWriter(SaveFileStream); int count = (this.chNum * this.databits) * ((int)this.sps_pers); byte[] buffer = new byte[count]; char[] chars = new char[this.binHeadSize]; byte[] buffer3 = new byte[count]; int seekOff = (int)((curTime - nodeData.fileStartTime).TotalSeconds) * 4000; input.Seek((long)this.headSize + seekOff, SeekOrigin.Begin); for (int j = 0; j < totalSeconds; j++) { reader.Read(buffer, 0, count); for (int k = 0; k < count; k += 4) { //buffer3[k] = buffer[k]; buffer3[k] = 0xFF; if (buffer[k + 3] == 0) { buffer3[k + 1] = 0xFF; } else { buffer3[k + 1] = buffer[k + 3]; } buffer3[k + 2] = buffer[k + 2]; buffer3[k + 3] = buffer[k + 1]; } DateTime time = curTime.AddSeconds((double)j); string[] strArray4 = new string[] { "$GPRMC,", time.Hour.ToString("00"), time.Minute.ToString("00"), time.Second.ToString("00"), ".00,A,", info.channel[0].Y.ToString("0000.00000"), ",N,", info.channel[0].X.ToString("00000.00000"), ",E,0.002,,", time.Day.ToString("00"), time.Month.ToString("00"), (time.Year - 0x7d0).ToString("00"), ",,,A*7\r\n" }; string str6 = string.Concat(strArray4); string[] strArray5 = new string[0x10]; strArray5[0] = "$$175B"; strArray5[1] = time.Year.ToString("0000"); strArray5[2] = "-"; strArray5[3] = time.Month.ToString("00"); strArray5[4] = "-"; strArray5[5] = time.Day.ToString("00"); strArray5[6] = " "; strArray5[7] = time.Hour.ToString("00"); strArray5[8] = ":"; strArray5[9] = time.Minute.ToString("00"); strArray5[10] = ":"; strArray5[11] = time.Second.ToString("00"); strArray5[12] = " "; strArray5[13] = (pointNum).ToString("00"); strArray5[14] = " "; strArray5[15] = str6; chars = string.Concat(strArray5).ToCharArray(); WriteLineSReader.Write(chars); WriteLineSReader.Write(buffer3); } input.Close(); reader.Close(); SaveFileStream.Close(); WriteLineSReader.Close(); } } public class StationModel { public string Name { get; set; } public int ID { get; set; } public double X { get; set; } public double Y { get; set; } /// /// 海拔 /// public double Z { get; set; } public double Size { get; set; } public Color Color { get; set; } = Color.Red; } }