Чтение объекта Stream без его использования - PullRequest
0 голосов
/ 06 февраля 2012

Я использую XML-RPC.NET (из http://www.xml -rpc.net / ) и метод HttpListener для прослушивания связи XML-RPC через определенный сетевой порт и ответа на него.

Тело входящего запроса доступно через HttpListenerContextInstance.Request.InputStream Потоковый объект:

HttpListener hlListener = new HttpListener();
HttpListenerContext hlcContext = hlListener.GetContext();
// hlcContext.Request.InputStream contains what I want

Доступ к потоку возможен из hlcContext.Request.InputStream, но этот поток недоступен для поиска, поэтому я не могу его прочитать / отобразить, а затем выполнить поиск в начале, чтобы библиотека XML-RPC.NET могла использовать его как это нужно. После прочтения он потребляется и не может быть перечитан.

Я понимаю, что одним из способов справиться с этой ситуацией было бы преобразование его из Stream в MemoryStream, который поддерживает поиск, однако я не знаю способа сделать это так, чтобы XML-RPC.NET продолжал используя MemoryStream вместо Stream. Просто копирование Stream в MemoryStream, кажется, потребляет Stream, что делает его непригодным для использования после этой точки:

// hlcContext.Request.InputStream is currently filled
MemoryStream msInput = new MemoryStream();
hlcContext.Request.InputStream.CopyTo(msInput);
byte[] byteInput = msInput.ToArray();
// hlcContext.Request.InputStream is now empty and XML-RPC.NET can no longer use it :(

Как я могу читать из Stream, чтобы я мог сохранить его в String, и чтобы Stream продолжал работать с XML-RPC.NET после этого момента?

Ответы [ 2 ]

1 голос
/ 06 февраля 2012

Если вы не можете найти законный путь, здесь есть способ установить поток на Request.InputStream (в крайнем случае)

MemoryStream msInput = new MemoryStream();
hlcContext.Request.InputStream.CopyTo(msInput);
byte[] byteInput = msInput.ToArray();
msInput.Seek(0, SeekOrigin.Begin);

request.GetType().InvokeMember("m_RequestStream", BindingFlags.SetField | BindingFlags.Instance | BindingFlags.NonPublic, null, request, new object[] { msInput });

Теперь вы можете свободно использовать byteInput

0 голосов
/ 06 февраля 2012

Это должно работать с потоком, который поддерживает поиск ( CanSeek == true).

MemoryStream msInput = new MemoryStream();
var preCopyPosition = hlcContext.Request.InputStream.Position;

hlcContext.Request.InputStream.CopyTo(msInput);
byte[] byteInput = msInput.ToArray();

// Go back to pre-copy state
hlcContext.Request.InputStream.Position = preCopyPosition;
...