当前位置: 首页 > article >正文

C#非常实用的技巧

1、解压和压缩

.NET Framework 4.5以上版本:

string zipFilePath = @"C:\path\to\file.zip";
        string destFolder = @"C:\path\to\destination\folder";

        using (var archive = ZipFile.OpenRead(zipFilePath))
        {
            foreach (var entry in archive.Entries)
            {
                // 如果是文件,则解压到指定目录
                if (!entry.FullName.EndsWith("/"))
                {
                    string destinationPath = Path.Combine(destFolder, entry.FullName);
                    entry.ExtractToFile(destinationPath, true);
                }
                // 如果是文件夹,则创建对应目录
                else
                {
                    Directory.CreateDirectory(Path.Combine(destFolder, entry.FullName));
                }
            }
        }

.NET Framework 4以下

虽然微软的net提供了很多解压和压缩的程序,但是如果你的系统是net Framework4,那上面的代码就用不了了,此时需要借用7za.exe

1.0 C# 解压文件

//放置7z的路径
            string Zip7FileName = Path.Combine("D:\\Project", "7za.exe");
            var tarArgs = string.Format("x \"{0}\" -o\"{1}\" -y", "待解压路径", "输出路径");
            using (var process = new Process())
            {
                process.StartInfo.FileName = Zip7FileName;
                process.StartInfo.Arguments = tarArgs;
                process.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
                process.StartInfo.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory;
                process.Start();
                process.WaitForExit();
            }

解压解释:

var tarArgs = string.Format("x \"{0}\" -o\"{1}\" -y", "待解压路径", "输出路径");

-y 参数表示 "yes to all",即自动回答 "yes",也就是在出现任何提示时都自动选择 "是"。这意味着 7z 命令行工具不会询问用户是否覆盖已有的文件、创建缺失的目录等等,而是直接按照默认行为执行。

例如,在以下语句中 -y 参数告诉 7z 命令行工具在解压缩文件时自动覆盖目标文件夹中已有的同名文件。

 
 

csharpCopy Code

var tarArgs = string.Format("x \"{0}\" -o\"{1}\" -y", "待解压路径", "输出路径");

-o 参数表示 "output directory",即指定解压缩后的文件输出目录。在 7z 命令行工具中,可以使用 -o 参数来指定输出目录的路径。例如,在以上语句中,-o"{1}" 参数将解压缩后的文件输出到名为 importzipedFolder 的目录中。

需要注意的是,7z 命令行工具只能解压缩一些特定的文件格式,例如.zip, .tar, .gz, .bz2 等等。如果需要解压缩其它类型的文件,可能需要使用相应的解压缩工具,并根据相应工具的使用方法来编写代码。

1.1 C# 压缩文件

//选择保存压缩包的的位置(此处以C:\Program Files (x86)\001.tar为例)
            string zipFilePath = "C:\Program Files (x86)\001.tar";
            StringBuilder tarArgs = new StringBuilder($"a -ttar \"{zipFilePath}\"");
            //需要压缩的文件夹
            DirectoryInfo dirInfo = new DirectoryInfo(Path.Combine(exportzipedFolder));
            foreach (var subDir in dirInfo.GetDirectories())
            {
                tarArgs.Append(" \"").Append(subDir.FullName).Append("\"");
            }
            using (var process = new Process())
            {
                process.StartInfo.FileName = Zip7FileName;
                process.StartInfo.Arguments = tarArgs.ToString();
                process.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
                process.StartInfo.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory;
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.CreateNoWindow = true;
                process.Start();
                process.WaitForExit();
            }
            if (Directory.Exists(exportzipedFolder))
            {
                Directory.Delete(exportzipedFolder, true);
            }

2 按位读取二进制

2.0 C#读取二进制

string filePath = "C:\Program Files (x86)\001.bin";
            using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                using (var reader = new BinaryReader(fs, Encoding.Default))
                {
                    //此处需要知道,需要读取多少位、用什么类型读取
                    var readType =Type;
                    object countent = new object();
                    switch (readType)
                    {
                        case Hmi.DataType.UInt16:
                            countent = reader.ReadUInt16();
                            break;
                        case Hmi.DataType.Int16:
                            countent = reader.ReadInt16();
                            break;
                        case Hmi.DataType.UInt32:
                            countent = reader.ReadUInt32();
                            break;
                        case Hmi.DataType.Int32:
                            countent = reader.ReadInt32();
                            break;
                        case Hmi.DataType.BCD16:
                            countent = reader.ReadUInt16();
                            break;
                        case Hmi.DataType.BCD32:
                            countent = reader.ReadInt32();
                            break;
                        case Hmi.DataType.Single:
                            countent = reader.ReadSingle();
                            break;
                        case Hmi.DataType.Double:
                            countent = reader.ReadDouble();
                            break;
                        case Hmi.DataType.String:
                            byte[] data = new byte[recipeDataType[i].StringLength];
                            int bytesRead = reader.Read(data, 0, data.Length);
                            string result = Encoding.Default.GetString(data, 0, bytesRead);
                            int byteCount = Encoding.Default.GetByteCount(result);
                            fs.Seek(byteCount, SeekOrigin.Current);
                            string str = string.Join("", result).TrimEnd('\0');
                            countent = str;
                            break;
                        case Hmi.DataType.Hex16:
                            countent = reader.ReadUInt16();
                            break;
                        case Hmi.DataType.Hex32:
                            countent = reader.ReadUInt16();
                            break;
                        case Hmi.DataType.Binary16:
                            countent = reader.ReadUInt16();
                            break;
                        case Hmi.DataType.Binary32:
                            countent = reader.ReadUInt16();
                            break;
                        case Hmi.DataType.UInt64:
                            countent = reader.ReadUInt64();
                            break;
                        case Hmi.DataType.Int64:
                            countent = reader.ReadInt64();
                            break;
                        case Hmi.DataType.Bool:
                            countent = reader.ReadInt16();
                            break;
                        default:
                            break;
                    }

                }
            }

 代码解释:读取二进制的时候,需要注意中文的读取方式,即类型中的string类型,如果需要读取18个字节,但是中文只有三个(UTF8编码中,中文占用3个字节,用Encoding.Default读取,默认使用的是GB2312编码,一个中文占用2个字节,ASCII码中一个中文也是占用2个字节)按照GB2312读取,实际只能读取到6个字节,此时18个字节是浪费掉的,此时需要使用调用fs.Seek(byteCount, SeekOrigin.Current);将文件流的当前位置移动指定的字节数;读取二进制还需要额外注意的类似的bool类型,bool类型在编程语言中是True和False,但是在二进制下只有1和0

2.0 C#写二进制

 string filePath = "C:\Program Files (x86)\001.bin";
            using (FileStream fileStream = new FileStream(filePath, FileMode.Create))
            {
                using (BinaryWriter writer = new BinaryWriter(fileStream, Encoding.Default))
                {
                    string content =String.Empty;
                    //此处需要知道,需要读取多少位、用什么类型读取
                    var readType = Type;
                    switch (readType)
                    {
                        case DataType.UInt16:
                            writer.Write(Convert.ToUInt16(content));
                            break;
                        case DataType.Int16:
                            writer.Write(Convert.ToUInt16(content));
                            break;
                        case DataType.UInt32:
                            writer.Write(Convert.ToUInt32(content));
                            break;
                        case DataType.Int32:
                            writer.Write(Convert.ToInt32(content));
                            break;
                        case DataType.BCD16:
                            writer.Write(Convert.ToUInt16(content));
                            break;
                        case DataType.BCD32:
                            writer.Write(Convert.ToInt32(content));
                            break;
                        case DataType.Single:
                            writer.Write(Convert.ToSingle(content));
                            break;
                        case DataType.Double:
                            writer.Write(Convert.ToDouble(content));
                            break;
                        case DataType.String:
                            //string类型需要处理需要读取多少位
                            int byteCount =100;
                            byte[] buffer = Encoding.Default.GetBytes(content);
                            if (buffer.Length < byteCount)
                            {
                                byte[] paddedBytes = new byte[byteCount];
                                Buffer.BlockCopy(buffer, 0, paddedBytes, 0, buffer.Length);
                                buffer = paddedBytes;
                            }
                            writer.Write(buffer, 0, byteCount);
                            fileStream.Seek(byteCount, SeekOrigin.Current);
                            break;
                        case DataType.Hex16:
                            writer.Write(Convert.ToUInt16(content));
                            break;
                        case DataType.Hex32:
                            writer.Write(Convert.ToUInt16(content));
                            break;
                        case DataType.Binary16:
                            writer.Write(Convert.ToUInt16(content));
                            break;
                        case DataType.Binary32:
                            writer.Write(Convert.ToUInt16(content));
                            break;
                        case DataType.UInt64:
                            writer.Write(Convert.ToUInt64(content));
                            break;
                        case DataType.Int64:
                            writer.Write(Convert.ToInt64(content));
                            break;
                        case DataType.Bool:
                            writer.Write(Convert.ToInt16(content));
                            break;
                        default:
                            break;
                    }
                }
            }

 和读二进制类型,写二进制依旧主要注意编码方式、读取的字节类型。以上代码能帮助我们读取二进制,但是请注意,我们读取的仅仅是某些位的数据,实际的二进制是长这样的:

 实际上,我们上面代码,仅仅读取了二进制文件39,用UTF-7(推荐使用UTF-7)编码GB2123读取出来的是57,没错,这么多00 01 02加那么多代码仅读取了一个57,后面的怎么读,可能需要根据实际情况进行考虑。

3、MQTT发布订阅

using System;
using System.Threading.Tasks;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Protocol;

public class MqttClient
{
    private IMqttClient mqttClient;

    public async Task ConnectAsync(string brokerIp, int brokerPort, string username, string password)
    {
        var factory = new MqttFactory();
        mqttClient = factory.CreateMqttClient();

        var options = new MqttClientOptionsBuilder()
            .WithTcpServer(brokerIp, brokerPort)
            .WithCredentials(username, password)
            .WithClientId("mqtt-client")
            .WithCleanSession()
            .Build();

        await mqttClient.ConnectAsync(options);
    }

    public void Disconnect()
    {
        if (mqttClient != null && mqttClient.IsConnected)
        {
            mqttClient.DisconnectAsync().Wait();
            mqttClient.Dispose();
            mqttClient = null;
        }
    }

    public async Task PublishAsync(string topic, string payload)
    {
        if (mqttClient == null || !mqttClient.IsConnected)
        {
            throw new InvalidOperationException("MQTT client is not connected.");
        }

        var message = new MqttApplicationMessageBuilder()
            .WithTopic(topic)
            .WithPayload(payload)
            .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtLeastOnce)
            .Build();

        await mqttClient.PublishAsync(message);
    }

    public async Task SubscribeAsync(string topic, Action<MqttApplicationMessageReceivedEventArgs> handler)
    {
        if (mqttClient == null || !mqttClient.IsConnected)
        {
            throw new InvalidOperationException("MQTT client is not connected.");
        }

        await mqttClient.SubscribeAsync(new TopicFilterBuilder()
            .WithTopic(topic)
            .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtLeastOnce)
            .Build());

        mqttClient.UseApplicationMessageReceivedHandler(handler);
    }

    public async Task UnsubscribeAsync(string topic)
    {
        if (mqttClient == null || !mqttClient.IsConnected)
        {
            throw new InvalidOperationException("MQTT client is not connected.");
        }

        await mqttClient.UnsubscribeAsync(topic);
    }
}

 低版本可能需要做一个兼容:
 

 private void Subscribe_ClickAsync(object sender, RoutedEventArgs e)
        {
            try
            {
                if (mqttClient == null || !mqttClient.IsConnected)
                {
                    throw new InvalidOperationException("MQTT client is not connected.");
                }
                mqttClient.SubscribeAsync(new MqttTopicFilterBuilder()
                   .WithTopic(txt_topic.Text)
                   .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtLeastOnce)
                   .Build());
                mqttClient.ApplicationMessageReceivedAsync += MqttClient_ApplicationMessageReceivedAsync1;
            }
            catch (Exception ex)
            {
                MessageBox.Show("系统异常:" + ex.Message);
            }
        }

        StringBuilder StringBuilder = new StringBuilder();
        private async Task MqttClient_ApplicationMessageReceivedAsync1(MqttApplicationMessageReceivedEventArgs arg)
        {
            try
            {
                this.Dispatcher.Invoke(new Action(delegate
                {
                    byte[] buffer = arg.ApplicationMessage.Payload;
                    string result = Encoding.Default.GetString(buffer, 0, buffer.Length);
                    StringBuilder.Append($"接受到:{result}\n");
                    txt_read.Text = StringBuilder.ToString();
                }));
               
            }
            catch (Exception ex)
            {
                MessageBox.Show("系统异常:" + ex.Message);
            }
        }

        private void Publish_ClickAsync(object sender, RoutedEventArgs e)
        {
            try
            {
                if (mqttClient == null || !mqttClient.IsConnected)
                {
                    throw new InvalidOperationException("MQTT client is not connected.");
                }
                byte[] payload = Encoding.Default.GetBytes(txt_writ.Text);

                var message = new MqttApplicationMessageBuilder()
                    .WithTopic(txt_topic.Text)
                    .WithPayload(payload)
                    .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtLeastOnce)
                    .Build();
                mqttClient.PublishAsync(message);
                txt_read.Text = StringBuilder.ToString();
            }
            catch (Exception ex)
            {
                MessageBox.Show("系统异常:" + ex.Message);
            }
        }


http://www.kler.cn/a/15106.html

相关文章:

  • thinkphp6模板调用URL方法生成的链接异常
  • 最优化方法_罚函数法例题
  • K8S资源限制之resources
  • 讯飞、阿里云、腾讯云:Android 语音合成服务对比选择
  • 网络爬虫 Python 第二课
  • 《基于 PySpark 的电影推荐系统分析及问题解决》
  • TCP/IP学习总结
  • Python学习之sh(shell脚本)在Python中的使用
  • 手机短信验证码登录功能的开发实录(机器识别码、短信限流、错误提示、发送验证码倒计时60秒)
  • 你不想成长,生活总会逼着你成长,阿里P8架构师分享十年学习生涯
  • 逻辑回归评分系统(mimic数据集)
  • Java设计模式-工厂模式
  • Vue打包后部署缓存问题处理方式
  • HBase正确使用方法
  • 【Linux从入门到精通】Linux常用基础指令(下)
  • netcore工程在linux下调用linux动态库
  • 借灰姑娘的手,讲述js混淆加密的美丽
  • 嵌入式设备显示屏相关概念汇总
  • 国内直接使用的ChatGTP
  • ThingsBoard教程(三六):规则节点解析 检查关系节点 check relation,实体类型节点 entity type
  • 蒸发器前氟离子超标的解决方法
  • KDJB-802C继电器成组保护校验仪
  • 2023年能源与环境工程国际会议(CFEEE 2023)
  • ES6对String字符串、Array数组、Number数字、Object对象 类型做了哪些升级优化
  • streamx平台部署
  • 1689_MATLAB处理Excel文件提升篇