20240815_FJEQ_upperpc_seabed/FujianEarthquake_seabed_UI/FujianEarthquake/Common/Tools.cs

699 lines
25 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace FujianEarthquake.Common
{
public static class Tools
{
/// <summary>
/// IP地址是否ping通
/// </summary>
/// <param name="strIP">IP地址例如“10.8.2.1”</param>
/// <returns></returns>
public static bool PingIp(string strIP)
{
bool bRet = false;
try
{
Ping pingSend = new Ping();
PingReply reply = pingSend.Send(strIP, 1000);
if (reply.Status == IPStatus.Success)
bRet = true;
}
catch (Exception)
{
bRet = false;
}
return bRet;
}
/// <summary>
/// 添加日志
/// </summary>
/// <param name="logstring"></param>
public static void AddLog(string logstring)
{
AddLgoToTXT("解析数据.txt", System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"数据记录\" + System.DateTime.Now.ToString("yyyy_MM_dd") + @"\", logstring);
}
/// <summary>
/// 文件自动保存
/// </summary>
/// <param name="_file_name">文件名称</param>
/// <param name="path">保存路径</param>
/// <param name="logstring">文件内容</param>
public static void AddLgoToTXT(string _file_name, string path, string logstring)
{
//检查是否存在该路径
if (!System.IO.Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
path = path + _file_name;
//检查该路径下是否存在该文件
if (!System.IO.File.Exists(path))
{
FileStream stream = null;
try
{
stream = System.IO.File.Create(path);
stream.Close();
stream.Dispose();
}
catch (Exception ex)
{
}
finally
{
if (stream != null)
{
stream.Close();
stream.Dispose();
}
}
}
if (!Txt_Used.ContainsKey(path))
{
Txt_Used.Add(path, true);
}
else
{
if (Txt_Used[path])
{
return;
}
else
{
Txt_Used[path] = true;
}
}
FileStream fs = null;
try
{
//[1]创建文件流 文件路径 和枚举类型的文件操作类型
fs = new FileStream(path, FileMode.Append);
//[2]创建写入器
StreamWriter sw = new StreamWriter(fs);
//[3]以流的方式写入数据
sw.Write(logstring);
//[4]关闭写入器
sw.Close();
//[5]关闭文件流
fs.Close();
Txt_Used[path] = false;
}
catch (Exception ex)
{
}
finally
{
if (fs != null)
{
fs.Close();
fs.Dispose();
}
}
}
static Dictionary<string, bool> Txt_Used = new Dictionary<string, bool>();
/// <summary>
/// 读取本地TXT文件
/// </summary>
/// <param name="_file_name"></param>
/// <param name="path"></param>
/// <returns></returns>
public static string ReadFromTXT(string _file_name, string path)
{
//检查是否存在该路径
if (!System.IO.Directory.Exists(path))
return "所选时间段没有系统日志";
path = path + _file_name;
//检查该路径下是否存在该文件
if (!System.IO.File.Exists(path))
return "所选时间段没有系统日志";
//如果文件占用就
if (FileIsInUse(new FileInfo(path)))
return "";
//[1]创建文件流
FileStream fs = new FileStream(path, FileMode.Open);
//【2】创建读取器
//Encoding.Default 读取未知文件是使用default格式
//StreamReader sr = new StreamReader(fs,Encoding.Default);
StreamReader sr = new StreamReader(fs);
//【3】以流的方式读取数据
string txt = sr.ReadToEnd();
//[4]关闭读取器
sr.Close();
//【5】关闭文件流
fs.Close();
return txt;
}
/// <summary>
/// 判断文件是否被占用
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
static bool FileIsInUse(FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
//如果文件被占用,即
//1.文件正在被另一个线程处理
//2.或者正在被另一个线程处理
//3.或者文件不存在
return true;
}
finally
{
if (stream != null)
stream.Close();
}
return false;
}
#region CRC校验
private static readonly byte[] aucCRCHi = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40
};
private static readonly byte[] aucCRCLo = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
0x41, 0x81, 0x80, 0x40
};
public static byte[] Crc16(byte[] pucFrame, int usLen)
{
int i = 0;
byte crcHi = 0xFF;
byte crcLo = 0xFF;
UInt16 iIndex = 0x0000;
while (usLen-- > 0)
{
iIndex = (UInt16)(crcLo ^ pucFrame[i++]);
crcLo = (byte)(crcHi ^ aucCRCHi[iIndex]);
crcHi = aucCRCLo[iIndex];
}
return new byte[] { crcLo, crcHi };
}
/// <summary>
/// CRC校验参数data为byte数组
/// </summary>
/// <param name="data">校验数据,字节数组</param>
/// <returns>字节1是高8位字节0是低8位</returns>
public static byte[] CRCCalc(byte[] data)
{
//crc计算赋初始值
int crc = 0xffff;
for (int i = 0; i < data.Length; i++)
{
crc = crc ^ data[i];
for (int j = 0; j < 8; j++)
{
int temp;
temp = crc & 1;
crc = crc >> 1;
crc = crc & 0x7fff;
if (temp == 1)
{
crc = crc ^ 0xa001;
}
crc = crc & 0xffff;
}
}
//CRC寄存器的高低位进行互换
byte[] crc16 = new byte[2];
crc16[0] = (byte)((crc >> 8) & 0xff);
crc16[1] = (byte)(crc & 0xff);
return crc16;
}
/// <summary>
/// CRC校验参数data为byte数组
/// </summary>
/// <param name="data">校验数据,字节数组</param>
/// <returns>字节0是高8位字节1是低8位</returns>
public static byte[] CRCCalcRev(byte[] data)
{
//crc计算赋初始值
int crc = 0xffff;
for (int i = 0; i < data.Length; i++)
{
crc = crc ^ data[i];
for (int j = 0; j < 8; j++)
{
int temp;
temp = crc & 1;
crc = crc >> 1;
crc = crc & 0x7fff;
if (temp == 1)
{
crc = crc ^ 0xa001;
}
crc = crc & 0xffff;
}
}
//CRC寄存器的高低位进行互换
byte[] crc16 = new byte[2];
crc16[1] = (byte)((crc >> 8) & 0xff);
crc16[0] = (byte)(crc & 0xff);
return crc16;
}
/// <summary>
/// CRC Modbus 低位在前,高位在后
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static byte[] CalculateModbusCRC(byte[] data)
{
ushort crc = 0xFFFF;
for (int i = 0; i < data.Length; i++)
{
crc ^= data[i];
for (int j = 0; j < 8; j++)
{
bool carry = (crc & 0x0001) > 0;
crc >>= 1;
if (carry)
{
crc ^= 0xA001;
}
}
}
return new byte[] { (byte)(crc & 0xFF), (byte)(crc >> 8) };
}
#endregion
#region CRC16-8005
private static readonly ushort[] _table = new ushort[256]
{
0,32773,32783,10,32795,30,20,32785,32819,54,60,32825,40,32813,32807,34,
32867,102,108,32873,120,32893,32887,114,80,32853,32863,90,32843,78,68,32833,
32963,198,204,32969,216,32989,32983,210,240,33013,33023,250,33003,238,228,32993,
160,32933,32943,170,32955,190,180,32945,32915,150,156,32921,136,32909,32903,130,
33155,390,396,33161,408,33181,33175,402,432,33205,33215,442,33195,430,420,33185,
480,33253,33263,490,33275,510,500,33265,33235,470,476,33241,456,33229,33223,450,
320,33093,33103,330,33115,350,340,33105,33139,374,380,33145,360,33133,33127,354,
33059,294,300,33065,312,33085,33079,306,272,33045,33055,282,33035,270,260,33025,
33539,774,780,33545,792,33565,33559,786,816,33589,33599,826,33579,814,804,33569,
864,33637,33647,874,33659,894,884,33649,33619,854,860,33625,840,33613,33607,834,
960,33733,33743,970,33755,990,980,33745,33779,1014,1020,33785,1000,33773,33767,994,
33699,934,940,33705,952,33725,33719,946,912,33685,33695,922,33675,910,900,33665,
640,33413,33423,650,33435,670,660,33425,33459,694,700,33465,680,33453,33447,674,
33507,742,748,33513,760,33533,33527,754,720,33493,33503,730,33483,718,708,33473,
33347,582,588,33353,600,33373,33367,594,624,33397,33407,634,33387,622,612,33377,
544,33317,33327,554,33339,574,564,33329,33299,534,540,33305,520,33293,33287,514
};
/// <summary>
/// C#CRC16 8005
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
public static byte[] ComputeChecksum(byte[] buffer)
{
ushort crc = 0;
for (int i = 0; i < buffer.Length; ++i)
{
crc = (ushort)((crc << 8) ^ _table[(crc >> 8) ^ buffer[i]]);
}
return new byte[]
{
(byte)(crc >> 8), // High byte
(byte)crc // Low byte
};
}
#endregion
#region 16ASCII
/// <summary>
/// 16进制转字符串ASCII
/// </summary>
/// <param name="hs"></param>
/// <param name="encode"></param>
/// <returns></returns>
public static string HexStringToString(string hs, Encoding encode)
{
StringBuilder strTemp = new StringBuilder();
byte[] b = new byte[hs.Length / 2];
for (int i = 0; i < hs.Length / 2; i++)
{
strTemp.Clear();
strTemp.Append(hs.Substring(i * 2, 2));
b[i] = Convert.ToByte(strTemp.ToString(), 16);
}
return encode.GetString(b);
}
#endregion
#region 162
/// <summary>
/// //16转2方法
/// </summary>
/// <param name="hexString"></param>
/// <returns></returns>
public static string HexString2BinString(string hexString)
{
try
{
string result = string.Empty;
foreach (char c in hexString)
{
int v = Convert.ToInt32(c.ToString(), 16);
int v2 = int.Parse(Convert.ToString(v, 2));
// 去掉格式串中的空格即可去掉每个4位二进制数之间的空格
result += string.Format("{0:d4} ", v2);
}
return result;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
}
#endregion
#region 16byte数组
// 将十六进制字符串转换为字节数组
public static byte[] HexStringToByteArray(string hexString)
{
if (!IsHexStringValid(hexString))
{
throw new ArgumentException("无效的十六进制字符串!", nameof(hexString));
}
return Enumerable.Range(0, hexString.Length / 2).Select(x => Convert.ToByte(hexString.Substring(x * 2, 2), 16)).ToArray();
}
// 验证十六进制字符串格式是否正确
private static bool IsHexStringValid(string hexString)
{
Regex regex = new Regex(@"^[A-Fa-f\d]+$");
return regex.Match(hexString).Success && hexString.Length % 2 == 0;
}
#endregion
#region
public static byte CheckSum(byte[] buffer)
{
byte sum = 0;
foreach (byte b in buffer)
{
sum += b;
}
return sum;
}
#endregion
#region
private static Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
/// <summary>
/// 获取配置文件
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static string GetAppSetting(string key)
{
if (ConfigurationManager.AppSettings.AllKeys.Contains(key))
{
string value = config.AppSettings.Settings[key].Value;
return value;
}
else
{
return null;
}
}
/// <summary>
/// 更新配置文件信息
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public static void UpdateAppSettings(string key, string value)
{
if (GetAppSetting(key) == value) //如果写入的配置文件和之前一致 就不写入了
return;
if (ConfigurationManager.AppSettings.AllKeys.Contains(key))
{
config.AppSettings.Settings[key].Value = value;
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");//刷新数据
}
else
{
Console.WriteLine("当前节点不存在!");
}
}
#endregion
#region
/// <summary>
/// 设置线程工作的空间
/// </summary>
/// <param name="process">线程</param>
/// <param name="minSize">最小空间</param>
/// <param name="maxSize">最大空间</param>
/// <returns></returns>
[System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
private static extern int SetProcessWorkingSetSize(IntPtr process, int minimumWorkingSetSize, int maximumWorkingSetSize);
public static void ClearMemory(object o)
{
GC.Collect();
GC.SuppressFinalize(o);
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
}
}
#endregion
public static float ConvertStringToTwoDecimalPlaces(string value)
{
try
{
return float.Parse(value, CultureInfo.CreateSpecificCulture("en-US"));
}
catch
{
// 处理转换失败的情况例如value不是有效的两位小数字符串
return 0.0f;
}
}
/// <summary>
/// 获取当前设备的所有端口号
/// </summary>
/// <returns></returns>
public static string[] GetSerialPort()
{
string[] ports = null;
ports = System.IO.Ports.SerialPort.GetPortNames();
return ports;
}
/// <summary>
/// 比较两个byte数组是否相等
/// </summary>
/// <param name="array1"></param>
/// <param name="array2"></param>
/// <returns></returns>
public static bool CompareByte(byte[] array1, byte[] array2)
{
if (array1 == null || array2 == null)
return false;
return array1.SequenceEqual(array2);
}
#region byte数组特定位置是否为1
public static bool IsBitSet(byte[] bytes, int position)
{
int arrayIndex = position / 8; // 计算byte数组的索引
int bitIndex = position % 8; // 计算位的索引0-7
// 确保索引没有超出数组范围
if (arrayIndex >= bytes.Length)
throw new IndexOutOfRangeException("Position is out of range of the byte array.");
byte b = bytes[arrayIndex];
// 使用位运算检查位是否为1
bool isSet = (b & (1 << bitIndex)) != 0;
return isSet;
}
#endregion
#region
public static byte[] ConvertHexToBinary(byte[] hexArray)
{
byte[] binaryArray = new byte[hexArray.Length * 8];
for (int i = 0; i < hexArray.Length; i++)
{
string binaryString = Convert.ToString(hexArray[i], 2);
// 补充到8位以确保每个byte都是8位
binaryString = binaryString.PadLeft(8, '0');
// 将二进制字符串转换为byte数组
for (int j = 0; j < 8; j++)
{
binaryArray[i * 8 + j] = Convert.ToByte(binaryString[j] - '0');
}
}
return binaryArray;
}
#endregion
#region IntToByte[4]
/// <summary>
/// int转化为byte[4]
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static byte[] IntToBytes(int value)
{
byte[] src = new byte[4];
src[0] = (byte)((value >> 24) & 0xFF);
src[1] = (byte)((value >> 16) & 0xFF);
src[2] = (byte)((value >> 8) & 0xFF);//高8位
src[3] = (byte)(value & 0xFF);//低位
return src;
}
#endregion
#region byte数组按长度在前面补0
/// <summary>
/// byte数组按长度在前面补0
/// </summary>
/// <param name="array"></param>
/// <param name="targetLength"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public static byte[] PadArrayWithZeros(byte[] array, int targetLength)
{
if (array == null)
throw new ArgumentNullException(nameof(array));
if (targetLength <= 0)
throw new ArgumentOutOfRangeException(nameof(targetLength), "Target length must be a positive integer.");
if (targetLength <= array.Length)
return array; // No need to pad
byte[] paddedArray = new byte[targetLength];
Array.Copy(array, 0, paddedArray, targetLength - array.Length, array.Length);
return paddedArray;
}
#endregion
public static byte[] DecimalToTwoByteArray(int decimalValue)
{
if (decimalValue < 0 || decimalValue > 65535)
{
throw new ArgumentOutOfRangeException(nameof(decimalValue), "Decimal value must be in the range of 0 to 65535.");
}
byte[] result = new byte[2];
result[0] = (byte)(decimalValue >> 8);
result[1] = (byte)(decimalValue & 0xFF);
return result;
}
}
}