【问题标题】:Notepad++ .NET plugin - get current buffer text -- encoding issuesNotepad++ .NET 插件 - 获取当前缓冲区文本 - 编码问题
【发布时间】:2013-07-02 15:17:03
【问题描述】:

我有一个 .NET 插件,它需要获取当前缓冲区的文本。我找到了这个page,它显示了一种方法:

public static string GetDocumentText(IntPtr curScintilla)
{
    int length = (int)Win32.SendMessage(curScintilla, SciMsg.SCI_GETLENGTH, 0, 0) + 1;
    StringBuilder sb = new StringBuilder(length);
    Win32.SendMessage(curScintilla, SciMsg.SCI_GETTEXT, length, sb);
    return sb.ToString();
}

这很好,直到我们遇到字符编码问题。我有一个在编码菜单中设置为“不带 BOM 的 UTF-8”的缓冲区,我将该文本写入文件:

System.IO.File.WriteAllText(@"C:\Users\davet\BBBBBB.txt", sb.ToString());

当我打开该文件(在记事本++中)时,编码菜单显示没有 BOM 的 UTF-8,但 ß 字符已损坏(ß)。

我能够找到当前缓冲区的编码:

int currentBuffer = (int)Win32.SendMessage(PluginBase.nppData._nppHandle, NppMsg.NPPM_GETCURRENTBUFFERID, 0, 0);
Console.WriteLine("currentBuffer: " + currentBuffer);
int encoding = (int) Win32.SendMessage(PluginBase.nppData._nppHandle, NppMsg.NPPM_GETBUFFERENCODING, currentBuffer, 0);
Console.WriteLine("encoding = " + encoding);

“没有 BOM 的 UTF-8”显示“4”,“ASCII”显示“0”,但我找不到 notepad++ 或 Scintilla 认为这些值应该代表什么。

所以我有点不知道下一步该去哪里(Windows 不是我的自然栖息地)。有谁知道我哪里出错了,或者如何进一步调试它?

谢谢。

【问题讨论】:

    标签: c# .net plugins notepad++ scintilla


    【解决方案1】:

    删除 StringBuilder 可解决此问题。

    public static string GetDocumentTextBytes(IntPtr curScintilla) {
    
        int length = (int) Win32.SendMessage(curScintilla, SciMsg.SCI_GETLENGTH, 0, 0) + 1;
        byte[] sb = new byte[length];
    
        unsafe {
            fixed (byte* p = sb) {
    
                IntPtr ptr = (IntPtr) p;
    
                Win32.SendMessage(curScintilla, SciMsg.SCI_GETTEXT, length, ptr);
            }
    
            return System.Text.Encoding.UTF8.GetString(sb).TrimEnd('\0');
        }
    }
    

    【讨论】:

      【解决方案2】:

      替代方法:

      UTF-8 字符损坏的原因是这一行..

      Win32.SendMessage(curScintilla, SciMsg.SCI_GETTEXT, length, sb);
      

      ..使用[MarshalAs(UnmanagedType.LPStr)] 读取字符串,它在解码字符串时使用计算机的默认ANSI 编码(MSDN)。这意味着您会得到一个每个字节一个字符的字符串,它会因多字节 UTF-8 字符而中断。

      现在,要将原始 UTF-8 字节保存到磁盘,您只需在写入文件时使用相同的默认 ANSI 编码:

      File.WriteAllText(@"C:\Users\davet\BBBBBB.txt", sb.ToString(), Encoding.Default);
      

      【讨论】:

        猜你喜欢
        • 2014-08-01
        • 2017-12-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-18
        • 1970-01-01
        相关资源
        最近更新 更多