问题
I'm using RichTextBox to convert a string in RTF to plain text, using this piece of code:
private string ConvertToText(string rtf)
{
if (string.IsNullOrWhiteSpace(rtf)) return string.Empty;
if (!rtf.Contains("{\\rtf")) return rtf.Trim();
using (var helper = new System.Windows.Forms.RichTextBox())
{
helper.Rtf = rtf;
var plainText = helper.Text;
if (string.IsNullOrWhiteSpace(plainText)) return string.Empty;
return "<< Rule in Rich Text Format converted to Plain Text >>\n\n"
+ plainText
+ "\n\n<< Rule in Rich Text Format converted to Plain Text >>";
}
}
It works OK on all developers machines, but it does not work when deployed to an Azure Web Site:
{
"$id" :"1",
"Message" :"An error has occurred.",
"ExceptionMessage":"Out of memory.",
"ExceptionType" :"System.OutOfMemoryException",
"StackTrace" :"
at System.Drawing.Graphics.FromHdcInternal(IntPtr hdc)\r\n
at System.Drawing.Font.GetHeight()\r\n
at System.Drawing.Font.get_Height()\r\n
at System.Windows.Forms.Control.get_FontHeight()\r\n
at System.Windows.Forms.TextBoxBase.get_PreferredHeight()\r\n
at System.Windows.Forms.TextBoxBase.AdjustHeight(Boolean returnIfAnchored)\r\n
at System.Windows.Forms.TextBoxBase.set_Multiline(Boolean value)\r\n
at System.Windows.Forms.RichTextBox.set_Multiline(Boolean value)\r\n
at System.Windows.Forms.RichTextBox..ctor()\r\n
at ... "
}
It happens no matter the size of the RTF string. I'm already using the "Copy to Local" property of the System.Windows.Forms
reference. Does anyone have experience in dealing with RTF and Azure? Is there an alternative way to convert RTF to plain text?
回答1:
This is an adapted C# version of this C++ forum link suggested by @Gusman on the comments:
public static string ConvertToText(string rtf)
{
bool slash = false; //indicates if backslash followed by the space
bool figure_opened = false; //indicates if opening figure brace followed by the space
bool figure_closed = false; //indicates if closing brace followed by the space
bool first_space = false; //the else spaces are in plain text and must be included to the result
if (rtf.Length < 4) return string.Empty;
int i = 0;
i = rtf.IndexOf("\\pard");
if (i < 1) return "";
var builder = new StringBuilder();
for (int j = i; j < rtf.Length - 1; j++)
{
char ch = rtf[j];
char nextCh = rtf[j + 1];
if (ch == '\\' && nextCh == 'p') // appends \n if \pard, except for first
{
if (j > i && j < rtf.Length - 4)
{
string fiveChars = rtf.Substring(j, 5);
if (fiveChars.Equals("\\pard"))
{
builder.Append("\n");
}
}
}
if (ch == '\\' && nextCh == 'u') // to deal correctly with special characters
{
string fourChars = rtf.Substring(j + 2, 4);
string digits = new string(fourChars.TakeWhile(char.IsDigit).ToArray());
char specialChar = (char)int.Parse(digits);
builder.Append(specialChar);
j += digits.Length + 5;
continue;
}
if (ch == '\\' && nextCh == '{') // if the text contains symbol '{'
{
slash = false;
figure_opened = false;
figure_closed = false;
first_space = false;
builder.Append('{');
j++;
continue;
}
else if (ch == '\\' && nextCh == '}') // if the text contains symbol '}'
{
slash = false;
figure_opened = false;
figure_closed = false;
first_space = false;
builder.Append('}');
j++;
continue;
}
else if (ch == '\\' && nextCh == '\\') // if the text contains symbol '\'
{
slash = false;
figure_opened = false;
figure_closed = false;
first_space = false;
builder.Append('\\');
j++;
continue;
}
else if (ch == '\\') // we are looking at the backslash
{
first_space = true;
slash = true;
}
else if (ch == '{')
{
first_space = true;
figure_opened = true;
}
else if (ch == '}')
{
first_space = true;
figure_closed = true;
}
else if (ch == ' ')
{
slash = false;
figure_opened = false;
figure_closed = false;
}
if (!slash && !figure_opened && !figure_closed)
{
if (!first_space)
{
builder.Append(ch);
}
else
{
first_space = false;
}
}
}
return builder.ToString();
}
It works! =D
来源:https://stackoverflow.com/questions/23277178/richtextbox-throws-outofmemory-on-azure