I figured I should post my current solution. It seems to work perfectly fine. Thank you Chris and Ants to the hints on how to go about doing this.
/// <summary>
/// Reads a TextRange (DataFormats.Rtf) from the stream.
/// </summary>
/// <param name="stream">The stream to be read from.</param>
/// <returns>The TextRange (DataFormats.Rtf) that was read from the stream.</returns>
public static TextRange ReadTextRange(FileStream stream)
{
long startPos = stream.Position;
int length = -1;
int count = 0;
int previousByte = 0;
int currentByte = 0;
//set previousByte to give the current one something to compare to
previousByte = stream.ReadByte();
//parse the file counting the { and } to find the end of the rtf portion of the file.
while (count > 0 || length < 1)
{
length++;
stream.Position = startPos + length;
currentByte = stream.ReadByte();
if (previousByte != 92) // not '\' so check to see if '{' or '}' is currentByte
{
if (currentByte == 123) // '{' increase count
count++;
else if (currentByte == 125) // '}' decrease count
count--;
}
previousByte = currentByte;
}
//save finish position to move to later
long finishPos = stream.Position;
//reset stream position to start at beginning of rtf
stream.Position = startPos;
//read the rtf portion of the file into a byte[]
byte[] content = new byte[length];
stream.Read(content, 0, length);
//put the byte[] into a memory stream
MemoryStream memStream = new MemoryStream(content);
FlowDocument doc = new FlowDocument();
TextRange range = new TextRange(doc.ContentStart, doc.ContentEnd);
//have the TextRange read from the memorystream
range.Load(memStream, System.Windows.DataFormats.Rtf);
memStream.Close();
//set the position to after the rtf portion of the file
stream.Position = finishPos;
return range;
}
This ReadTextRange Method is in a StreamHelper class I defined for helping read from a FileStream. So all of this is to load a TextRange that is saved to the FileStream like this...
//save query (TextRange)
Query.Save(stream, System.Windows.DataFormats.Rtf);
I hope that someone finds this useful if/when they come to a similar problem! :D
EDIT:
I used a profiler and found that this code was not very efficient so I have changed this code to be much more efficient in a few ways.
Instead of using the TextRange and use a byte[] which holds the contents of MemoryStream memStream. This cuts out range.Load which consumes a lot of CPU.
I took out the line stream.Position = startPos + length because I realized it was useless after the first run and also took up a decent amount of CPU. I placed stream.Position--; after the line previousByte = stream.ReadByte();
Also I realized I was being a bad coder and wasn't following MVC by having TextRange, UI element, inside of my data class. Now it has a byte[], which is MUCH better.
EDIT AGAIN:
After a few minutes of having the byte[] instead of the TextRange I realized I had the size of the byte[] so I didn't need to parse it. So instead I save write the byte[] size and then the byte[]. This makes it extremely fast and can read a very large file nearly instantly.