gpt4 book ai didi

using block 中的 C# 语句返回 null

转载 作者:太空宇宙 更新时间:2023-11-03 16:58:39 25 4
gpt4 key购买 nike

我是 C# 新手,对下一个示例感到好奇:

假设我们有这样的代码:

private static byte[] Compress(byte[] data)
{
var output = new MemoryStream();
using (var deflateStream = new DeflateStream(output, CompressionLevel.Fastest))
{
deflateStream.Write(data, 0, data.Length);
}
return output.ToArray();
}

并且:

private static byte[] Compress(byte[] data)
{
using (var output = new MemoryStream())
using (var deflateStream = new DeflateStream(output, CompressionLevel.Fastest))
{
deflateStream.Write(data, 0, data.Length);
return output.ToArray();
}
}

第一个示例按预期工作,而后者仅返回 null。using 在内部是如何工作的?我希望它像简单的 try/finally 一样工作,但它似乎在调用 toArray 之前关闭了 MemoryStream

另一方面,下面的代码也按预期工作,这带来了更多的神秘感:

private static byte[] Decompress(byte[] payload)
{
using(var inputStream = new MemoryStream(payload))
using(var outputStream = new MemoryStream())
using (var deflateStream = new DeflateStream(inputStream, CompressionMode.Decompress))
{
deflateStream.CopyTo(outputStream);
return outputStream.ToArray();
}
}

最佳答案

您看到的行为是因为对于许多 Stream 实现,写入流的数据不一定会立即执行并推送到其最终目的地。这可能是出于性能原因,例如 FileStream 在物理写入磁盘之前缓冲内存中的数据以写入,或者因为在所有输入数据可用之前不知道最终输出 - 例如一个加密流,其中输出必须是特定大小并且数据的末尾可能必须被填充。因此,除非您确定实现,否则您只能假设一旦 Stream 被释放或关闭,所有数据都可用。

所以在你的第一个例子中,

private static byte[] Compress(byte[] data)
{
var output = new MemoryStream();
using (var deflateStream = new DeflateStream(output, CompressionLevel.Fastest))
{
deflateStream.Write(data, 0, data.Length);
}
return output.ToArray();
}

这里的 using 语句处理 DeflateStream 触发它将所有输出发送到 MemoryStream。您在 MemoryStream 上调用 ToArray(),它会得到您期望的输出。

但是,在您的第二个示例中:

using (var output = new MemoryStream())
using (var deflateStream = new DeflateStream(output, CompressionLevel.Fastest))
{
deflateStream.Write(data, 0, data.Length);
return output.ToArray();
}

您正在返回 MemoryStream 的内容 before DeflateStream 被释放,因为调用在第二个 using block 。那时,DeflateStream 还没有调用 Dispose 触发它把压缩数据写入输出流,所以 MemoryStream 是空,你得到一个空结果。

对于最后一个示例,CopyTo 通常从一个流读取到缓冲区,然后将该缓冲区写入目标流,直到读取所有输入数据。所以在这种情况下,它之所以有效,是因为在您返回结果之前,数据仍然写入了 MemoryStream

关于using block 中的 C# 语句返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56327362/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com