我试图修改文件流,但我遇到了一些有趣的事情。当我从原始流中读取一个字符串然后尝试将其写入一个新流时,我最终会得到比原始流更大的字符串。
我没有发现任何类似的问题。有人可以澄清发生了什么吗?我介入并注意到变量的大小
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或文本文件无关紧要,字节仍然是字节,所以如果我有一个输入0110 0001 0110 0010 0110 0011 0110 0100
,我希望仍然可以读取4个字节。即使我把它读作字符串' abcd',如果我完全按照我发现的那样写回二进制文件,它也不会对我有所影响。
为什么一个Stream给我的长度为84863,而另一个流给我的长度为151950?
修改: 我尝试使用StreamReader构造函数来尝试读取编码:
var reader = new StreamReader(input, true);
以后写出时使用相同的编码:
new StreamWriter(output, reader.CurrentEncoding).Write(contents);
..无济于事。同样的问题。
答案 0 :(得分:2)
您的信息流包含非UTF-8的二进制数据。 StreamReader(Stream)
的默认构造函数使用UTF-8解码器,用Unicode replacement character,U+FFFD
替换无法识别的字节序列。
假设输入流包含五个字节41 80 81 82 7A
。然后new StreamReader(input).ReadToEnd()
返回字符串"A���z"
,因为0x80
(以及0x81
和0x82
)无法解码为C#char
使用UTF-8编码。
调用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
。