0

我目前正在尝试弄清楚如何将 RichTextbox 中的内容保存到流中(当前使用 FileStream),并与一堆其他数据一起执行此操作。然后当然我希望能够从这个文件中加载。我目前正在尝试使用以下内容。

FileStream stream = new FileStream(); //this is actually correctly defined.
ASCIIEncoding encoding = new ASCIIEncoding();

//write Title
byte[] array = encoding.GetBytes(Title);
stream.WriteByte(Convert.ToByte(array.Length));
stream.Write(array, 0, array.Length);

//save textRange
textRange.Save(stream, System.Windows.DataFormats.Rtf);

//write Subtitle
byte[] array = encoding.GetBytes(Subtitle);
stream.WriteByte(Convert.ToByte(array.Length));
stream.Write(array, 0, array.Length);
//ect...and something very similar for Loading a file.

这基本上就是我想要做的。我实际上保存了 2 个 TextRanges 和更多的属性。所以我的问题是 TextRange.Load() 读取到文件的末尾......考虑到我有 2 个需要保存/加载的 TextRanges,我无法使用它。所以在这里我试图想出另一种方法来保存/加载 RichTextBox 的内容和其他数据。我不必使用流。我对任何可行的解决方案都持开放态度。提前致谢!

~杰森

4

2 回答 2

0

您可以加载/保存到 MemoryStream 以解决读取到文件末尾的问题。它可能看起来像这样:

  • 将文件加载到内存中
  • 将该文件中作为富文本框内容的部分加载到 MemoryStream 中
  • 从该 MemoryStream 加载 Richtextbox 内容

或者您想知道如何创建和解析文件以包含标题、内容和任何其他字段的不同部分?

于 2009-03-27T05:39:33.443 回答
0

我想我应该发布我当前的解决方案。它似乎工作得很好。感谢 Chris 和 Ants 提供有关如何执行此操作的提示。

/// <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 方法位于我为帮助从 FileStream 读取而定义的 StreamHelper 类中。所以这一切都是为了加载一个像这样保存到 FileStream 的 TextRange ......

//save query (TextRange)
        Query.Save(stream, System.Windows.DataFormats.Rtf);

我希望有人在遇到类似问题时发现这很有用!:D

编辑:

我使用了一个分析器,发现这段代码效率不高,所以我改变了这段代码,使其在一些方面更有效率。

  1. 而不是使用 TextRange 并使用包含 MemoryStream memStream 内容的 byte[]。这会减少 range.Load 消耗大量 CPU 的时间。

  2. 我取出了行 stream.Position = startPos + length 因为我意识到它在第一次运行后没用,并且还占用了相当多的 CPU。我放置了stream.Position--; 在 previousByte = stream.ReadByte(); 行之后

此外,我意识到我是一个糟糕的编码员,并且没有通过在我的数据类中包含 TextRange、UI 元素来遵循 MVC。现在它有一个字节[],这要好得多。

再次编辑:

在使用 byte[] 而不是 TextRange 几分钟后,我意识到我有 byte[] 的大小,所以我不需要解析它。因此,我保存写入字节 [] 大小,然后写入字节 []。这使得它非常快,几乎可以立即读取一个非常大的文件。

于 2009-03-29T09:39:24.847 回答