Чтение из основного потока (httpRequestStream) - PullRequest
5 голосов
/ 15 января 2012

У меня есть основной поток, который является потоком HTTP-запроса, и

var s=new HttpListener().GetContext().Request.InputStream;

Я хочу прочитать поток (который содержит не-символьное содержимое, потому что я отправил пакет)

Когда мы обертываем этот поток StreamReader, мы используем функцию ReadToEnd () StreamReader, он может прочитать весь поток и вернуть строку ...

HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://127.0.0.1/");
listener.Start();
var context = listener.GetContext();
var sr = new StreamReader(context.Request.InputStream);
string x=sr.ReadToEnd(); //This Workds

, но так как он имеет контент, отличный от символов, мы не можемиспользовать StremReader (я перепробовал все механизмы кодирования .. используя строку просто неправильно). И я не могу использовать функцию

context.Request.InputStream.Read(buffer,position,Len) 

, потому что я не могу получить длину потока, InputStream.Length всегда выдает исключение ине может быть использовано ... и я не хочу создавать небольшой протокол, такой как [размер] [файл] и читать сначала размер, а затем файл ... каким-то образом StreamReader может получить длину ... и я просто хочу знать, как.Я также попробовал это, и это не сработало

List<byte> bb = new List<byte>();
var ss = context.Request.InputStream;
byte b = (byte)ss.ReadByte();
while (b >= 0)
{
    bb.Add(b);
    b = (byte)ss.ReadByte();
}

Я решил это следующим образом

FileStream fs = new FileStream("C:\\cygwin\\home\\Dff.rar", FileMode.Create);
byte[] file = new byte[1024 * 1024];
int finishedBytes = ss.Read(file, 0, file.Length);
while (finishedBytes > 0)
{
    fs.Write(file, 0, finishedBytes);
    finishedBytes = ss.Read(file, 0, file.Length);
}
fs.Close();

спасибо Джон, Дуглас

Ответы [ 3 ]

6 голосов
/ 15 января 2012

Ваша ошибка находится в следующей строке:

byte b = (byte)ss.ReadByte();

Тип byte не подписан;когда Stream.ReadByte возвращает -1 в конце потока, вы без разбора приводите его к byte, который преобразует его в 255 и, следовательно, удовлетворяет условию b >= 0.По этой причине полезно отметить, что тип возвращаемого значения int, а не byte.

Быстрое и грязное исправление для вашего кода:

List<byte> bb = new List<byte>();
var ss = context.Request.InputStream;
int next = ss.ReadByte();
while (next != -1)
{
    bb.Add((byte)next);
    next = ss.ReadByte();
}

Следующее решение является более эффективным, поскольку оно позволяет избежать побайтного чтения, вызванного вызовами ReadByte, и вместо этого использует динамически расширяемый байтовый массив для вызовов Read (аналогично тому, как List<T> внутреннереализовано):

var ss = context.Request.InputStream;

byte[] buffer = new byte[1024];
int totalCount = 0;

while (true)
{
    int currentCount = ss.Read(buffer, totalCount, buffer.Length - totalCount);
    if (currentCount == 0)
        break;

    totalCount += currentCount;
    if (totalCount == buffer.Length)
        Array.Resize(ref buffer, buffer.Length * 2);
}

Array.Resize(ref buffer, totalCount);
5 голосов
/ 15 января 2012

StreamReader также не может получить длину - кажется, есть некоторая путаница в отношении третьего параметра Stream.Read.Этот параметр указывает максимальное число байтов, которые будут прочитаны, которые не должны (и не могут) быть равными количеству байтов, фактически доступных в потоке.Вы просто вызываете Read в цикле, пока он не вернет 0, и в этом случае вы знаете, что достигли конца потока.Все это задокументировано в MSDN, и это также точно, как StreamReader делает это.

Также нет проблем при чтении запроса с помощью StreamReader и получении его в string;Строки бинарно безопасны в .NET, так что вы покрыты.Проблема будет состоять в том, чтобы разобраться в содержимом строки, но мы не можем говорить об этом, поскольку вы не предоставляете никакой соответствующей информации.

0 голосов
/ 09 декабря 2016

HttpRequestStream не даст вам длину, но вы можете получить ее из свойства HttpListenerRequest.ContentLength64.Как сказал Джон, убедитесь, что вы соблюдаете возвращаемое значение из метода Read.В моем случае мы получаем буферизованные чтения и не можем прочитать всю полезную нагрузку в 226 КБ за один раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...