Изменить RTF как обычный текст, но не могу открыть его снова - PullRequest
1 голос
/ 01 сентября 2011

У меня есть файл 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);
        }

1 Ответ

4 голосов
/ 01 сентября 2011

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, - запись в файл напрямую и вообще не использование потока памяти - если нет других причин, по которым вы делаете это, это кажется наиболее простым решением. , это упростит ваш код и позволит избежать буферизации файла в памяти.

...