【问题标题】:Why is this copy Stream larger than its original Stream?为什么这个副本 Stream 比它的原始 Stream 大?
【发布时间】:2017-04-25 22:28:49
【问题描述】:

我正在尝试修改文件流,但遇到了一些有趣的事情。当我从原始流中读取一个字符串,然后尝试将其写入一个新流时,我最终会得到比原始流更大的大小。

我没有发现任何类似的问题。有人可以澄清发生了什么吗?我逐步检查并记录了变量的大小

private Stream CopyAndChangeStreamContents(Stream input)
{
    input.Position = 0; //input.Length is (long)84863 

    string contents = new StreamReader(input).ReadToEnd(); //contents.Length is (int)80765 

    Stream output = new MemoryStream();
    new StreamWriter(output).Write(contents); //output.Length is (long)151950 

    output.Flush();
    return output;
}

编辑 #2 Downvoter:该方法的 cmets 和意图并没有解释这里发生了什么。无论正在读取什么类型的数据,我都想了解是什么底层流特性导致了如此巨大的大小差异

读取字节时,不管它来自 zip 文件还是文本文件,字节仍然是字节,所以如果我有输入 0110 0001 0110 0010 0110 0011 0110 0100,我希望仍会读取 4 个字节。即使我将其读取为字符串“abcd”,如果我完全按照我找到的方式写回二进制文件,它也不会对我产生影响。

为什么一个 Stream 给我的长度是 84863,而另一个 Stream 给我的长度是 151950?

编辑: 我尝试使用 StreamReader 构造函数来尝试读取编码:

var reader = new StreamReader(input, true);

然后在写出时使用相同的编码:

new StreamWriter(output, reader.CurrentEncoding).Write(contents);

..无济于事。同样的问题。

【问题讨论】:

  • 原始源文件可能是ASCII,但你写的是UTF8。如果您只想复制文件,则不应将它们视为文本。
  • 这样input.CopyTo(output) 就可以了。
  • 我尝试设置编码但没有运气。我会用代码更新问题
  • @PixelCakeGames 您是否尝试将 DOCX 文件作为字符串读取?如果是这样,那就行不通了。 DOCX 基本上是一个包含一堆 XML 文件的 ZIP 文件——它是实际描述文档的 XML 文件。您需要编辑 XML 文件 - 通常的方法是使用 OpenXML SDK 或围绕它的更易于使用的包装器之一。
  • @PixelCakeGames 肯定与您正在阅读的文字有关...

标签: c# .net memory stream


【解决方案1】:

您的流包含非 UTF-8 的二进制数据。 StreamReader(Stream) 的默认构造函数使用 UTF-8 解码器,将无法识别的字节序列替换为 Unicode replacement characterU+FFFD

假设输入流包含五个字节41 80 81 82 7A。然后new StreamReader(input).ReadToEnd() 返回字符串"A���z",因为0x80(以及0x810x82)无法使用UTF-8 编码解码为C# char

调用new StreamWriter(output).Write() 将该字符串编码为UTF-8 并将其写入输出流。 U+FFFD 以 UTF-8 编码为三字节序列 EF BF BD。所以在这个例子中,它会写出 11 个字节:41 EF BF BD EF BF BD EF BF BD 7A

无法识别的字节到 � 到 EF BF BD 的转换解释了为什么当你读然后写时你的流会变大。

解决办法是读写byte[],而不是将任意二进制数据转换成string

【讨论】:

  • 这正是我正在寻找的解释。我通过阅读byte[] 并检查大小来验证您所说的内容。很好的洞察力
猜你喜欢
  • 1970-01-01
  • 2021-01-24
  • 2011-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-19
相关资源
最近更新 更多