Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern search in a System.IO.Stream

Tags:

c#

stream

I am receiving System IO Streams from a source. I will proceed with the stream object only if it contains the string "MSTND".

I realize there is not much I can do on the stream unless I convert it into string. The string conversion is only for sub-string matching. But I don't want to do anything that takes up lot of time or space. How time / space intensive is a conversion from Stream to string just for sub-string matching?

The code I have written is:

private bool StreamHasString (Stream vStream)
{
     bool containsStr = false;
     byte[] streamBytes = new byte[vStream.Length];
     vStream.Read( streamBytes, 0, (int) vStream.Length);
     string stringOfStream = Encoding.UTF32.GetString(streamBytes);
     if (stringOfStream.Contains("MSTND"))
     {
        containsStr = true;
     }     
     return containsStr ;
}
like image 859
santra_a Avatar asked Apr 09 '13 06:04

santra_a


2 Answers

What you are doing would work fine, but once you have read the stream into a string, you could just return the string so that you don't have to read the stream again.

Note also that you are using the Read method wrong. It returns the number of bytes read intot he array, because it doesn't have to return as many bytes as you requested, even if it's not at the end of the stream. You have to loop until you have read all the bytes from the stream.

private string StreamHasString (Stream vStream) {
  byte[] streamBytes = new byte[vStream.Length];

  int pos = 0;
  int len = (int)vStream.Length;
  while (pos < len) {
    int n = vStream.Read(streamBytes, pos, len - pos);
    pos += n;
  }

  string stringOfStream = Encoding.UTF32.GetString(streamBytes);
  if (stringOfStream.Contains("MSTND")) {
    return stringOfStream;
  } else {
    return null;
  }
}

Usage:

string s = StreamHasString(vStream);
if (s != null) {
  // proceed
}
like image 78
Guffa Avatar answered Oct 26 '22 10:10

Guffa


Depending on where in the stream you're expecting this sequence it would be fairly efficient to convert to a string to perform the substring. If its in a standard spot each time then you can read through the number of bytes required and convert them to a string.

Take a look at this for some reference: http://msdn.microsoft.com/en-us/library/system.io.stream.read.aspx

Alternatively you could convert the string "MSTND" to a byte[] and search the stream for the byte[].

Edit:

I found How do I get a consistent byte representation of strings in C# without manually specifying an encoding? which should help with converting the string to byte[].

like image 32
iambeanie Avatar answered Oct 26 '22 09:10

iambeanie