首页 > 解决方案 > 在 C# 中重写 PowerShell 函数

问题描述

我目前正在用 C# 重写一些 PowerShell 模块,主要是为了学习该语言并掌握 C# 开发。到目前为止,它运行得非常好,重写和测试了大约 20 个函数。

我坚持的一个是压缩 GZip 字符串。我已经设法使用其他人编写的函数来完成任务,但我(现在仍然)无法直接翻译我的 PowerShell 函数。

原始 PowerShell 代码:

$ms = New-Object System.IO.MemoryStream
$cs = New-Object System.IO.Compression.GZipStream($ms, [System.IO.Compression.CompressionMode]::Compress)
$sw = New-Object System.IO.StreamWriter($cs)
$sw.Write($StringToCompress)
$sw.Close();
[System.Convert]::ToBase64String($ms.ToArray()) | Out-File $FilePath -Force | Out-Null
$cs.Close();
$ms.Close();

C# 等效项(忽略 void,正在 LINQPad 中进行测试):

public static void CompressString(string stringToCompress)
{
    var memoryStream = new MemoryStream();
    var compression = new GZipStream(memoryStream, CompressionMode.Compress, true);
    var streamWriter = new StreamWriter(compression);

    Console.WriteLine("String to compress: " + stringToCompress);

    streamWriter.Write(stringToCompress);

    Console.WriteLine("Base64 encoded compressed string: " + 
    Convert.ToBase64String(memoryStream.ToArray()));
}

PowerShell 代码完美运行,但 C# 没有返回任何内容。为什么会这样,因为我相信我的“翻译”是正确的?

在此处输入图像描述

提醒一下,我已经在另一个人的帮助下解决了我的问题,但现在我正在研究为什么上述方法不起作用。

标签: c#powershell

解决方案


如评论中所述,您的两个示例之间存在细微差别。PowerShell 版本之所以有效,是因为$sw.Close()它会导致流编写器在关闭之前刷新其缓冲区。

在 C# 版本中,您永远不会关闭它 - 因此,当您调用时memoryStream.ToArray(),无法保证编写器实际上已完成对底层流的写入。

C# 中的惯用方法是利用using()语句获取IDisposable资源,如下所示:

Console.WriteLine("String to compress: " + stringToCompress);
using(var memoryStream = new MemoryStream())
{
    using(var compression = new GZipStream(memoryStream, CompressionMode.Compress, true))
    using(var streamWriter = new StreamWriter(compression))
    {
        streamWriter.Write(stringToCompress);
    }

    Console.WriteLine("Base64 encoded compressed string: " + 
        Convert.ToBase64String(memoryStream.ToArray()));
}

在上面的示例中,streamWriterandcompression流将在您从内存流中读取时被释放,并且当您从方法返回时,andmemoryStream也将被自动释放。


推荐阅读