C# 为什么此复制流比其原始流大?

C# 为什么此复制流比其原始流大?,c#,.net,memory,stream,C#,.net,Memory,Stream,我试图修改一个文件流,我遇到了一些有趣的事情。当我从原始流中读取一个字符串,然后尝试将其写入一个新的流中时,我最终得到的字符串比原始流大 我没有发现任何类似的问题。有人能澄清发生了什么事吗?我一步一步走过,注意到了变量的大小 private Stream CopyAndChangeStreamContents(Stream input) { input.Position = 0; //input.Length is (long)84863 string contents =

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

我没有发现任何类似的问题。有人能澄清发生了什么事吗?我一步一步走过,注意到了变量的大小

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:该方法的评论和意图并不能解释这里发生了什么。无论读取的是哪种类型的数据,我都想了解是什么底层流特性导致了如此巨大的大小差异

当读取字节时,不管它是来自zip还是文本文件,字节仍然是字节,因此如果我有一个输入
0110001 0110010 0110 0011 0110 0100
,我仍然希望读取4个字节。即使我把它读作字符串'abcd',如果我把二进制文件写回原样,对我来说也不会有什么不同

为什么一条流的长度为84863,而另一条流的长度为151950?

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

var reader=newstreamreader(输入,true)

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

新建StreamWriter(输出、读卡器、CurrentEncoding).Write(内容)


…没有用。同样的问题。

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

让我们假设输入流包含五个字节
418081827a
。然后
newstreamreader(input).ReadToEnd()返回字符串
“A���z“
,因为无法使用UTF-8编码将
0x80
(和
0x81
0x82
)解码为C#
char

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

将无法识别的字节转换为� to
EF-BF-BD
解释了为什么在读写流时,流的大小会增加


解决方案是读取和写入
字节[]
,而不是将任意二进制数据转换为
字符串

原始源文件可能是ASCII,但您正在写入UTF8。如果你只想复制文件,就不应该把它们当作文本。这样
input.CopyTo(output)
就可以了。我试着设置了编码,但没有成功。我将用code@PixelCakeGames您正在尝试将DOCX文件作为字符串读取吗?如果是这样,那就行不通了。DOCX基本上是一个包含大量XML文件的ZIP文件——实际上描述文档的是XML文件。您需要编辑XML文件-通常的方法是使用或其中一个更容易使用的包装器。@PixelCakeGames肯定与您正在阅读的文本有关……这正是我想要的解释。我通过读取
字节[]
并检查大小来验证您所说的内容。很有洞察力