热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C#中对字符串进行压缩和解压的实现_C#教程

本文主要介绍了C#中对字符串进行压缩和解压的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着

利用GZip和Brotli压缩方法的优势,减少字符串数据的大小,提高.NET核心应用程序的性能。

在开发应用程序时,你经常需要处理字符串。由于字符串对象在性能方面的成本很高,你经常想压缩你的字符串内容,即字符串对象中的数据,以减少有效载荷。有几个库可以做到这一点,但两个流行的技术是GZip和Brotli。

在这篇文章中,我们将讨论如何在C#中使用GZip和Brotli算法对字符串进行压缩和解压。要使用这里提供的代码示例,你的系统中应该安装有Visual Studio 2022。如果你还没有副本,你可以在这里下载Visual Studio 2022。

在Visual Studio 2022中创建一个控制台应用程序项目

首先,让我们在Visual Studio中创建一个.NET Core控制台应用程序项目。假设你的系统中已经安装了Visual Studio 2022,按照下面的步骤创建一个新的.NET Core控制台应用程序项目:


  • 启动Visual Studio IDE。

  • 点击 "创建一个新项目"。

  • 在 "创建一个新项目 "窗口中,从显示的模板列表中选择 "控制台应用程序"。

  • 点击 "下一步"。

  • 在接下来显示的 "配置你的新项目 "窗口中,指定新项目的名称和位置。

  • 在 "其他信息 "窗口中,选择.NET 6.0作为运行时间,然后点击下一步。

  • 点击 "创建"。

我们将使用这个项目来说明下面的字符串压缩和解压缩。但首先我们要安装一个基准测试包BenchmarkDotNet,它将使我们能够衡量我们从压缩中获得的好处。

安装BenchmarkDotNet NuGet包

基准测试代码对于了解你的应用程序的性能至关重要。在这篇文章中,我们将利用BenchmarkDotNet来跟踪方法的性能。

要使用BenchmarkDotNet,你必须安装BenchmarkDotNet软件包。你可以通过Visual Studio 2022里面的NuGet软件包管理器,或者在NuGet软件包管理器控制台执行以下命令来完成。

Install-Package BenchmarkDotNet

C#中的System.IO.Compression命名空间

System.IO.Compression命名空间包括压缩文件和字符串的方法。它包含两种压缩算法。GZip 和 Brotli。在接下来的章节中,我们将研究如何在C#中使用GZip和Brotli压缩算法对字符串数据进行压缩和解压。

我们将在下面的例子中使用以下文本。

string originalString = "To work with BenchmarkDotNet you must install the BenchmarkDotNet package. " +
"You can do this either via the NuGet Package Manager inside the Visual Studio 2019 IDE, " +
"or by executing the Install-Package BenchmarkDotNet command at the NuGet Package Manager Console";

在C#中使用GZip对数据进行压缩和解压

下面的代码片断显示了如何在C#中使用GZipStream类来压缩数据。注意,压缩方法的参数是一个字节数组:

public static byte[] Compress(byte[] bytes)
{
using (var memoryStream = new MemoryStream())
{
using (var gzipStream = new GZipStream(memoryStream, CompressionLevel.Optimal))
{
gzipStream.Write(bytes, 0, bytes.Length);
}
return memoryStream.ToArray();
}
}

要解压使用GZip算法压缩过的数据,我们可以使用以下方法:

public static byte[] Decompress(byte[] bytes)
{
using (var memoryStream = new MemoryStream(bytes))
{
using (var outputStream = new MemoryStream())
{
using (var decompressStream = new GZipStream(memoryStream, CompressionMode.Decompress))
{
decompressStream.CopyTo(outputStream);
}
return outputStream.ToArray();
}
}
}

运行GZip压缩算法

你可以使用下面的代码片断来执行我们刚刚创建的GZip压缩方法:

byte[] dataToCompress = Encoding.UTF8.GetBytes(originalString);
byte[] compressedData = GZipCompressor.Compress(dataToCompress);
string compressedString = Encoding.UTF8.GetString(compressedData);
Console.WriteLine("Length of compressed string: " + compressedString.Length);
byte[] decompressedData = GZipCompressor.Decompress(compressedData);
string deCompressedString = Encoding.UTF8.GetString(decompressedData);
Console.WriteLine("Length of decompressed string: " + deCompressedString.Length);

当你运行上述代码时,你会在控制台窗口看到以下输出:

图1.GZip将原来259个字符的字符串压缩成167个字符。

请注意,GZip从原始的259个字符的字符串中修剪了92个字符。因为原始字符串和解压后的字符串应该是相同的,它们的长度也应该是相同的。

在C#中使用Brotli对数据进行压缩和解压

下面的代码片断说明了如何在C#中使用BrotliStream类来压缩数据。与上面的GZip例子一样,注意压缩方法的参数是一个字节数组:

public static byte[] Compress(byte[] bytes)
{
using (var memoryStream = new MemoryStream())
{
using (var brotliStream = new BrotliStream(memoryStream, CompressionLevel.Optimal))
{
brotliStream.Write(bytes, 0, bytes.Length);
}
return memoryStream.ToArray();
}
}

而这里是你如何使用BrotliStream来解压数据的:

public static byte[] Decompress(byte[] bytes)
{
using (var memoryStream = new MemoryStream(bytes))
{
using (var outputStream = new MemoryStream())
{
using (var decompressStream = new BrotliStream(memoryStream, CompressionMode.Decompress))
{
decompressStream.CopyTo(outputStream);
}
return outputStream.ToArray();
}
}
}

运行Brotli压缩算法

下面的代码片断显示了你如何使用我们上面创建的Brotli压缩方法来压缩一个字符串:

Console.WriteLine("Length of original string: " + originalString.Length);
byte[] dataToCompress = Encoding.UTF8.GetBytes(originalString);
byte[] compressedData = BrotliCompressor.Compress(dataToCompress);
string compressedString = Convert.ToBase64String(compressedData);
Console.WriteLine("Length of compressed string: " + compressedString.Length);
byte[] decompressedData = BrotliCompressor.Decompress(compressedData);
string deCompressedString = Convert.ToBase64String(decompressedData);
Console.WriteLine("Length of decompressed string: " + deCompressedString.Length);

当你运行该程序时,你将在控制台窗口看到以下输出:

图2.Brotli将原来259个字符的字符串压缩成121个字符。

正如你所看到的,Brotli的压缩效果比GZip好得多。然而,压缩率并不是故事的全部,我们将在下面看到。

用GZip和Brotli进行异步压缩和解压

请注意,我们之前使用的压缩和解压方法也有异步的对应方法。这里是使用GZip算法的压缩和解压方法的异步版本:

public async static Task CompressAsync(byte[] bytes)
{
using (var memoryStream = new MemoryStream())
{
using (var gzipStream = new GZipStream(memoryStream, CompressionLevel.Optimal))
{
await gzipStream.WriteAsync(bytes, 0, bytes.Length);
}
return memoryStream.ToArray();
}
}


public async static Task DecompressAsync(byte[] bytes)
{
using (var memoryStream = new MemoryStream(bytes))
{
using (var outputStream = new MemoryStream())
{
using (var decompressStream = new GZipStream(memoryStream, CompressionMode.Decompress))
{
await decompressStream.CopyToAsync(outputStream);
}
return outputStream.ToArray();
}
}
}

这里是使用Brotli的压缩和解压方法的异步版本:

public static async Task CompressAsync(byte[] bytes)
{
using (var memoryStream = new MemoryStream())
{
using (var brotliStream = new BrotliStream(memoryStream, CompressionLevel.Optimal))
{
await brotliStream.WriteAsync(bytes, 0, bytes.Length);
}
return memoryStream.ToArray();
}
}


public static async Task DecompressAsync(byte[] bytes)
{
using (var memoryStream = new MemoryStream(bytes))
{
using (var outputStream = new MemoryStream())
{
using (var brotliStream = new BrotliStream(memoryStream, CompressionMode.Decompress))
{
await brotliStream.CopyToAsync(outputStream);
}
return outputStream.ToArray();
}
}
}

在C#中用GZip和Brotli进行压缩和解压的基准测试

在我们之前创建的控制台应用程序项目中,创建一个名为BenchmarkCompression.cs的新文件并输入以下代码:

[MemoryDiagnoser]
[Orderer(BenchmarkDotNet.Order.SummaryOrderPolicy.FastestToSlowest)]
[RankColumn]
public class BenchmarkCompression
{
string originalString = "To work with BenchmarkDotNet you must install the BenchmarkDotNet package. " +
"You can do this either via the NuGet Package Manager inside the Visual Studio 2019 IDE, " +
"or by executing the Install-Package BenchmarkDotNet command at the NuGet Package Manager Console";
[Benchmark]
public void GZipCompress()
{
byte[] dataToCompress = Encoding.UTF8.GetBytes(originalString);
var compressedData = GZipCompressor.Compress(dataToCompress);
}
[Benchmark]
public void BrotliCompress()
{
byte[] dataToCompress = Encoding.UTF8.GetBytes(originalString);
var compressedData = BrotliCompressor.Compress(dataToCompress);
}
}

当你运行基准时,你应该看到类似于下面图3所示的控制台输出。

图3.来自BenchmarkDotNet的结果...GZip赢了!

显然,在选择压缩算法时,压缩率并不是唯一的考虑因素。尽管与GZip相比,你可以使用Brotli实现更好的压缩,但额外的压缩是以性能为代价的。GZip在压缩和解压数据方面明显比Brotli快。

当对你的.NET应用程序进行基准测试时,你应该始终确保你的项目在发布模式下运行。原因是编译器为调试和发布模式优化代码的方式不同。关于基准测试和应用程序的性能,我在以后的文章中会有更多论述。


推荐阅读
  • Linux操作系统回炉复习各种常用命令集合解析
    Linux操作系统回炉复习各种常用命令集合解析猿码互联猿码互联今天Linux终端命令格式目标了解终端命令格式知道如何查阅终端命令帮助信息01.终端命令格式command[ ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 在使用Visual Studio 2019评估Blazor时,将taghelper添加到剃刀文件时会出现错误。错误信息是"标记助手:@addTagHelper *,BlazorPOC.Validations"。需要在文件顶部添加@using语句"@using BlazorPOC.Validations"来解决这个问题。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • 解决.net项目中未注册“microsoft.ACE.oledb.12.0”提供程序的方法
    在开发.net项目中,通过microsoft.ACE.oledb读取excel文件信息时,报错“未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序”。本文提供了解决这个问题的方法,包括错误描述和代码示例。通过注册提供程序和修改连接字符串,可以成功读取excel文件信息。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • 本文记录了作者对x265开源代码的实现与框架进行学习与探索的过程,包括x265的下载地址与参考资料,以及在Win7 32 bit PC、VS2010平台上的安装与配置步骤。 ... [详细]
  • mapreduce原理_MapReduce原理及WordCount实践
    参考链接:https:www.cnblogs.comlaowangcp8961946.html一、MapReduce流程1.1Mapreduce整体流程: ... [详细]
  • 本文介绍了pack布局管理器在Perl/Tk中的使用方法及注意事项。通过调用pack()方法,可以控制部件在显示窗口中的位置和大小。同时,本文还提到了在使用pack布局管理器时,应注意将部件分组以便在水平和垂直方向上进行堆放。此外,还介绍了使用Frame部件或Toplevel部件来组织部件在窗口内的方法。最后,本文强调了在使用pack布局管理器时,应避免在中间切换到grid布局管理器,以免造成混乱。 ... [详细]
  • Introduction(简介)Forbeingapowerfulobject-orientedprogramminglanguage,Cisuseda ... [详细]
author-avatar
凌微茵_686
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有