开发者

Edit RTF as plain text but unable to open it again

开发者 https://www.devze.com 2023-04-01 03:11 出处:网络
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 cod

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);
        }


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号