C#非常实用的技巧

这篇具有很好参考价值的文章主要介绍了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;
                    }
                }
            }

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

 实际上,我们上面代码,仅仅读取了二进制文件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);
    }
}

 低版本可能需要做一个兼容:
 文章来源地址https://www.toymoban.com/news/detail-429522.html

 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);
            }
        }

到了这里,关于C#非常实用的技巧的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 实用指南:C#中优雅更新GUI的基础和高级技巧(WinForms和WPF)

      概述: 以上内容详细介绍了在C#中如何从另一个线程更新GUI,包括基础功能和高级功能。对于WinForms,使用`Control.Invoke`;对于WPF,使用`Dispatcher.Invoke`。高级功能使用`SynchronizationContext`实现线程间通信,确保清晰、可读性高的代码。 在C#中,从另一个线程更新GUI通常需要使用

    2024年03月18日
    浏览(47)
  • Linux :: 压缩与解压指令【1】:zip / unzip 指令:压缩与解压用法详解

    前言:本篇是 Linux 基本操作篇章的内容! 笔者使用的环境是基于腾讯云服务器:CentOS 7.6 64bit。 学习集: C++ 入门到入土!!!学习合集 Linux 从命令到网络再到内核!学习合集 目录索引: 1. 基本用法及功能 2. 基本用法:压缩/解压指定文件【注意代码示例内容!】 3. 「-r」

    2024年01月25日
    浏览(56)
  • zip解压和压缩

    引言 介绍zip文件的概念 涉及到的Java类和包: java.util.zip https://blog.csdn.net/u012998680/article/details/126060855 压缩文件 准备压缩的源文件和目标zip文件的路径 创建 FileOutputStream 和 ZipOutputStream 对象 创建源文件的 File 和 FileInputStream 对象 创建 ZipEntry 对象,并设置其名称为源文件的名

    2024年02月11日
    浏览(84)
  • Linux文件压缩与解压

    目录 1、分步压缩 1.1、文件打包 1.2、关于为何需要f参数 1.3、压缩包 2、分步解压 2.1、解压 2.2、解包 3、一步压缩与解压       在Windows上我们常用压缩软件完成文件的压缩,在Linux上我们可以使用命令来完成文件压缩。         首先,任意创建两个测试文件:main.c 和 test。

    2024年02月08日
    浏览(38)
  • Linux的压缩与解压

    一、tar命令 常用组合: 1.tar -cvf test.tar 1.txt 2.txt 3.txt :将3个文本文件压缩到test.tar文件内 2.tar -zcvf test.tar.gz 1.txt 2.txt :将2个文件压缩到test.tar.gz文件内 1.tar -xvf test.tar 2.tar -zxvf test.tar.gz -C /home 将文件解压到指定目录 二、zip命令 语法:zip [-r] 参数1 参数2 参数3 .... -r:压缩文

    2024年01月21日
    浏览(40)
  • Linux下压缩解压命令

    2.命令:gzip 特点:只能压缩文件,压缩后原文件删除,生成 xxx.gz文件 压缩: 用法:gzip [需压缩文件] 解压: 用法:gunzip [压缩包] 3.命令:bzip2 特点:只能压缩文件,压缩后原文件删除,生成 xxx.bz2 压缩: 用法:bzip2 [需压缩文件] 解压: 用法:bunzip2 [压缩包] 4.命令:tar 特

    2024年02月06日
    浏览(43)
  • Linux 压缩解压

      (注:tar是打包,不是压缩!) 解包:tar xvf FileName.tar -C DirName 打包:tar cvf FileName.tar DirName 解压1:gunzip FileName.gz 解压2:gzip -d FileName.gz 压缩:gzip FileName 解压:tar zxvf FileName.tar.gz -C DirName 压缩:tar zcvf FileName.tar.gz DirName 解压1:bzip2 -d FileName.bz2 解压2:bunzip2 FileName.bz2 压缩

    2024年01月19日
    浏览(40)
  • 【方法】7Z压缩包如何解压?

    你知道7Z压缩包如何解压吗? 7Z是一种主流高效的压缩格式,它可以用多种压缩解压软件来解压,像7-Zip、WinRAR等常用的解压缩软件都可以解压7Z压缩包。 首先我们可以从官网或者软件商店里免费下载7-Zip或者WinRAR解压缩软件,再安装在电脑里。 安装完成后,用鼠标选中压缩包

    2024年02月13日
    浏览(44)
  • Linux 压缩和解压

    1、tar命令(复杂) 使用tar命令均可以进行压缩和解压缩的操作 语法:tar [-c -v -x -f -z -C] 参数1 参数2 ... 参数N -c,创建压缩文件,用于压缩模式 -v,显示压缩、解压过程,用于查看进度 -x,解压模式 -f,要创建的文件,或要解压的文件,-f选项必须在所有选项中位置处于最后

    2024年02月07日
    浏览(39)
  • java 解压rar压缩包

    记录下引入maven的相关坐标后,在archivers包下没有找到rar包 Java本身不提供解压RAR压缩包的功能,需要借助第三方库来实现。以下是使用Apache Commons Compress库来解压RAR压缩包的示例代码: 这个示例代码通过解析RAR文件的文件头来提取压缩包中的文件。在解压过程中,他们将提取

    2024年02月11日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包