Я решил опубликовать свое текущее решение. Кажется, работает отлично. Спасибо Крис и Муравьи за подсказки о том, как это сделать.
/// <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;
}
Этот метод ReadTextRange находится в классе StreamHelper, который я определил для помощи в чтении из FileStream. Так что все это - загрузить TextRange, который сохраняется в FileStream, как это ...
//save query (TextRange)
Query.Save(stream, System.Windows.DataFormats.Rtf);
Я надеюсь, что кто-то найдет это полезным, если / когда он столкнется с подобной проблемой! : D
EDIT:
Я использовал профилировщик и обнаружил, что этот код не очень эффективен, поэтому я изменил этот код, чтобы сделать его несколько более эффективным.
Вместо использования TextRange и использования байта [], который содержит содержимое MemoryStream memStream. Это сокращает диапазон. Загрузка, которая потребляет много ресурсов процессора.
Я вынул строку stream.Position = startPos + length, потому что понял, что это было бесполезно после первого запуска, а также занял приличное количество процессора. Я поместил поток. Позиция--; после строки previousByte = stream.ReadByte ();
Кроме того, я понял, что я плохой кодер и не следую MVC, имея TextRange, элемент пользовательского интерфейса, внутри моего класса данных. Теперь у него есть байт [], который НАМНОГО лучше.
ИЗМЕНИТЬ СНОВА:
После нескольких минут использования байта [] вместо TextRange я понял, что у меня есть размер байта [], поэтому мне не нужно было его анализировать. Так что вместо этого я сохраняю записать размер байта [], а затем байта []. Это делает его чрезвычайно быстрым и может читать очень большой файл почти мгновенно.