Почему StringWriter.ToString возвращает `System.Byte[]`, а не данные?
UnZipFile
метод записывает данные из inputStream
в outputWriter
, Зачем sr.ToString()
возвращается System.Byte[]
а не данные?
using (var sr = new StringWriter())
{
UnZipFile(response.GetResponseStream(), sr);
var content = sr.ToString();
}
public static void UnZipFile(Stream inputStream, TextWriter outputWriter)
{
using (var zipStream = new ZipInputStream(inputStream))
{
ZipEntry currentEntry;
if ((currentEntry = zipStream.GetNextEntry()) != null)
{
var size = 2048;
var data = new byte[size];
while (true)
{
size = zipStream.Read(data, 0, size);
if (size > 0)
{
outputWriter.Write(data);
}
else
{
break;
}
}
}
}
}
3 ответа
Проблема на линии:
outputWriter.Write(data);
StringWriter.Write
не имеет перегрузки, ожидая byte[]
, Следовательно, Write(Object)
называется вместо. И согласно MSDN:
Записывает текстовое представление объекта в текстовую строку или поток, вызывая метод ToString для этого объекта.
призвание ToString
на байтовом массиве возвращает System.byte[]
, объясняя, как вы получаете эту строку в вашем StringWriter
,
Причина проста:
data
имеет тип byte[]
, Там нет перегрузки для byte[]
на StringWriter
поэтому он использует перегрузку для объекта. А потом звонит ToString()
в байтовом массиве в штучной упаковке, который просто печатает тип.
Ваш код эквивалентен этому:
outputWriter.Write(data.ToString());
theateist,
Глядя на другие ответы здесь, я должен согласиться с тем, что причина, по которой "ToString()" возвращает System.Byte[], заключается в том, что именно это вы вкладываете в него, а все, что помещено в StringWriter, вызывает его собственное. Метод "ToString" при этом. (т.е. byte[].toString() = "System.byte[]"). На самом деле вся идея в том, что StringWriter предназначен только для записи в строку "buffer" (StringBuilder), поэтому теоретически, если ваш файл был достаточно большим (больше 2048), вы получите "System.Byte[]System"..Byte[]" (и т. Д.). Попробуйте это сделать в потоке памяти, а затем прочитать из этого потока, может быть лучшее понимание того, что вы смотрите. (Код не проверен, просто пример).
using (Stream ms = new MemoryStream())
{
UnZipFile(response.GetResponseStream(), ms);
string content;
ms.Position = 0;
using(StreamReader s = new StreamReader(ms))
{
content = s.ReadToEnd();
}
}
public static void UnZipFile(Stream inputStream, Stream outputWriter)
{
using (var zipStream = new ZipInputStream(inputStream))
{
ZipEntry currentEntry;
if ((currentEntry = zipStream.GetNextEntry()) != null)
{
int size = 2048;
byte[] data = new byte[size];
while (true)
{
size = zipStream.Read(data, 0, size);
if (size > 0)
{
outputWriter.Write(data);
}
else
{
break;
}
}
}
}
}
Другая идея на самом деле заключается в использовании endcoding для получения строки
public string UnZipFile(Stream inputStream)
{
string tmp;
using(Stream zipStream = new ZipInputStream(inputStream))
{
ZipEntry currentEntry;
if(currentEntry = zipStream.GetNextEntry()) != null)
{
using(Stream ms = new MemoryStream())
{
int size = 2048;
byte[] data = new byte[size];
while(true)
{
if((size = zipStream.Read(data,0,size)) > 0)
ms.Write(data);
else
break;
}
tmp = Encoding.Default.GetString(ms.ToByteArray());
}
}
}
}
return tmp;
}
Или, как последняя идея, вы могли бы изменить свой исходный код, чтобы иметь
outputWriter.Write(Encoding.Default.GetString(data));
Вместо
outputWriter.Write(data);
Кстати, пожалуйста, избегайте ключевого слова var в сообщениях, может быть, просто мой любимый пив, но код менее читабелен при использовании слабых типов.