将 RTF 编辑为纯文本但无法再次打开

发布于 2024-12-03 01:32:56 字数 2034 浏览 0 评论 0原文

我有一个 RTF 文件,我想打开它,替换字符串“TEMPLATE_Name”并保存。但保存后,文件无法再次正确打开。当我使用 MS Word 时,文件会打开并显示 RTF 原始代码而不是文本。

我担心我正在破坏格式或编码,但我真的不知道如何:

        using (MemoryStream ms = new MemoryStream(1000))
        using (StreamWriter sw = new StreamWriter(ms,Encoding.UTF8))
        {
            using (Stream fsSource = new FileStream(Server.MapPath("~/LetterTemplates/TestTemplate.rtf"), FileMode.Open))
            using (StreamReader sr = new StreamReader(fsSource,Encoding.UTF8))
                while (!sr.EndOfStream)
                {
                    String line = sr.ReadLine();
                    line = line.Replace("TEMPLATE_Name", model.FirstName + " " + model.LastName);
                    sw.WriteLine(line);
                }

            ms.Position = 0;

            using (FileStream fs = new FileStream(Server.MapPath("~/LetterTemplates/test.rtf"), FileMode.Create))
                ms.CopyTo(fs);
        }

知道可能是什么问题吗?

谢谢。

解决方案:一个问题是@BrokenGlass 指出的,事实上我没有刷新流。另一个是编码。在 RTF 文件的第一行中,我可以看到:

{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\

因此,即使对 RTF 没有任何了解,我将编码设置为代码页 1252 并且它可以工作:

        using (MemoryStream ms = new MemoryStream(1000))
        using (StreamWriter sw = new StreamWriter(ms,Encoding.GetEncoding(1252)))
        {
            using (Stream fsSource = new FileStream(Server.MapPath("~/LetterTemplates/TestTemplate.rtf"), FileMode.Open))
            using (StreamReader sr = new StreamReader(fsSource,Encoding.GetEncoding(1252)))
                while (!sr.EndOfStream)
                {
                    String line = sr.ReadLine();
                    line = line.Replace("TEMPLATE_Name", model.FirstName + " " + model.LastName);
                    sw.WriteLine(line);
                }

            sw.Flush();
            ms.Position = 0;

            using (FileStream fs = new FileStream(Server.MapPath("~/LetterTemplates/test.rtf"), FileMode.Create))
                ms.CopyTo(fs);
        }

I have a RTF file that I want to open, replace a String "TEMPLATE_Name" and save. But after saving, the file cannot open correctly again. When I use MS Word, the file opens and shows the RTF raw code instead the text.

I am afraid I am breaking the format or the encoding but I don't really know how:

        using (MemoryStream ms = new MemoryStream(1000))
        using (StreamWriter sw = new StreamWriter(ms,Encoding.UTF8))
        {
            using (Stream fsSource = new FileStream(Server.MapPath("~/LetterTemplates/TestTemplate.rtf"), FileMode.Open))
            using (StreamReader sr = new StreamReader(fsSource,Encoding.UTF8))
                while (!sr.EndOfStream)
                {
                    String line = sr.ReadLine();
                    line = line.Replace("TEMPLATE_Name", model.FirstName + " " + model.LastName);
                    sw.WriteLine(line);
                }

            ms.Position = 0;

            using (FileStream fs = new FileStream(Server.MapPath("~/LetterTemplates/test.rtf"), FileMode.Create))
                ms.CopyTo(fs);
        }

Any idea about what could be the issue?

Thanks.

SOLUTION: One problem was what @BrokenGlass has pointed out, the fact I was not flushing the stream. The other was the encoding. In the fist line of the RTF file I can see:

{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\

So, even without understand anything about RTF, I set the encoding to code page 1252 and it works:

        using (MemoryStream ms = new MemoryStream(1000))
        using (StreamWriter sw = new StreamWriter(ms,Encoding.GetEncoding(1252)))
        {
            using (Stream fsSource = new FileStream(Server.MapPath("~/LetterTemplates/TestTemplate.rtf"), FileMode.Open))
            using (StreamReader sr = new StreamReader(fsSource,Encoding.GetEncoding(1252)))
                while (!sr.EndOfStream)
                {
                    String line = sr.ReadLine();
                    line = line.Replace("TEMPLATE_Name", model.FirstName + " " + model.LastName);
                    sw.WriteLine(line);
                }

            sw.Flush();
            ms.Position = 0;

            using (FileStream fs = new FileStream(Server.MapPath("~/LetterTemplates/test.rtf"), FileMode.Create))
                ms.CopyTo(fs);
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

苍风燃霜 2024-12-10 01:32:56

StreamWriter 正在缓冲内容 - 确保在从内存流读取之前调用 sw.Flush()

StreamWriter.Flush()< /a>:

清除当前写入器的所有缓冲区并导致任何缓冲数据
写入底层流。

根据评论进行编辑:

@leppie 提到的更好替代方案是重构代码以使用 using 块强制刷新,而不是显式执行此操作:

 using (MemoryStream ms = new MemoryStream(1000))
 {
   using (StreamWriter sw = new StreamWriter(ms,Encoding.UTF8))
   {
     //...
   }
   ms.Position = 0;
   //Write to file
 }

>更好的正如@Slaks指出的替代方案是直接写入文件而不使用内存流 - 除非有其他原因你这样做这似乎是最简单的解决方案,它会简化你的代码并避免在内存中缓冲文件。

StreamWriter is buffering content - make sure you call sw.Flush() before reading from your memory stream.

StreamWriter.Flush():

Clears all buffers for the current writer and causes any buffered data
to be written to the underlying stream.

Edit in light of comments:

A better alternative as @leppie alluded to is restructuring the code to use the using block to force flushing, instead of explicitly doing it:

 using (MemoryStream ms = new MemoryStream(1000))
 {
   using (StreamWriter sw = new StreamWriter(ms,Encoding.UTF8))
   {
     //...
   }
   ms.Position = 0;
   //Write to file
 }

An even better alternative as @Slaks pointed out is writing to the file directly and not using a memory stream at all - unless there are other reasons you are doing this this seems to be the most straightforward solution, it would simplify your code and avoid buffering the file in memory.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文