You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

更新加密JSON遇MemoryStream不可扩展异常及代码调整求助

异常原因分析及代码合理性确认

一、"Memory stream is not expandable"异常原因

最初的代码触发异常的核心原因有两点:

  1. MemoryStream不可扩展:用固定长度byte[]初始化的MemoryStream,底层依赖静态数组,不支持动态扩容。而CryptoStream在Write模式下加密数据时,需要向流写入内容并可能扩展流容量,因此直接抛出NotSupportedException。
  2. 逻辑错误:原代码将序列化后的JSON转成字节数组存入MemoryStream,又试图通过CryptoStream往同一个只读内存流写入数据,完全不符合加密逻辑——加密应该是将明文数据传入加密流,最终输出到可写的目标载体(如文件),而非往固定长度的内存流写数据。

二、调整后代码的合理性确认

调整后的代码改用File.Create()创建可写的FileStream作为CryptoStream的底层流,解决了原异常的根本问题,整体逻辑方向正确,但仍有几个细节需要优化:

1. 编码一致性问题

当前代码用Encoding.ASCII.GetBytes(newContent)转换JSON字符串,ASCII编码无法处理非ASCII字符(如中文、特殊符号),会导致数据丢失。应改为和序列化逻辑一致的Encoding.UTF8:

cryptoStream.Write(Encoding.UTF8.GetBytes(newContent));

2. 确保加密数据完全写入

CryptoStream内部有缓冲区,仅依赖using块自动释放可能无法保证所有加密数据都写入文件。建议在Write后显式调用FlushFinalBlock(),强制清空缓冲区:

cryptoStream.Write(Encoding.UTF8.GetBytes(newContent));
cryptoStream.FlushFinalBlock();

3. 显式配置AES参数

AES的默认模式(CBC)和填充方式(PKCS7)虽然通用,但显式指定能避免不同环境下的默认值差异,提升代码兼容性:

using Aes aesProvider = Aes.Create();
aesProvider.Key = Convert.FromBase64String(Key);
aesProvider.IV = Convert.FromBase64String(IV);
aesProvider.Mode = CipherMode.CBC; // 显式指定加密模式
aesProvider.Padding = PaddingMode.PKCS7; // 显式指定填充方式

4. 异常处理补充

实际场景中,文件操作(如权限不足、路径无效)和加密操作(如Key/IV长度不合法)都可能抛出异常,建议添加必要的异常捕获逻辑,避免程序直接崩溃。

优化后的完整代码示例

public void SetLevelData(GameLevel value) 
{
    var newContent = JsonConvert.SerializeObject(value);

    using FileStream stream = File.Create(GetJSONPath());

    using Aes aesProvider = Aes.Create();
    aesProvider.Key = Convert.FromBase64String(Key);
    aesProvider.IV = Convert.FromBase64String(IV);
    aesProvider.Mode = CipherMode.CBC;
    aesProvider.Padding = PaddingMode.PKCS7;

    using ICryptoTransform cryptoTransform = aesProvider.CreateEncryptor();
    using CryptoStream cryptoStream = new CryptoStream(stream, cryptoTransform, CryptoStreamMode.Write);

    byte[] plainBytes = Encoding.UTF8.GetBytes(newContent);
    cryptoStream.Write(plainBytes, 0, plainBytes.Length);
    cryptoStream.FlushFinalBlock();
}

内容的提问来源于stack exchange,提问作者Newboy11

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 20:47:45