【问题标题】:OpenFileDialog filename as UTF8OpenFileDialog 文件名为 UTF8
【发布时间】:2009-06-19 08:54:10
【问题描述】:

这里有 C# 问题..

我有一个 UTF-8 字符串,它正在由 C++ 中的非 Unicode 程序解释。此文本显示不正确,但据我所知,它是完整的,然后用作输出文件名。 .

无论如何,在 C# 项目中,我正在尝试使用 System.Windows.Forms.OpenFileDialog 对象打开此文件。我从这个对象的 .FileNames[] 获得的文件名是 Unicode (UCS-2)。但是,这个字符串被误解了。例如,如果原始字符串是 0xe3 0x81 0x82,则 FileName[].ToCharArray() 显示它现在是 0x00e3 0x0081 0x201a .... .. 看起来 OpenFileDialog 对象只是填充了它,但事实并非如此。在 OpenFileDialog 生成的第三个字符中,它是不同的,我无法弄清楚这个字节发生了什么..

我的问题是:有没有办法将 OpenFileDialog 框中突出显示的文件名视为 UTF-8?

我认为这无关紧要,但如果您需要知道,字符串是日文的..

谢谢,

克雷布

更新

首先,感谢所有在这里提出建议的人,非常感谢他们。

现在,要回答修改 C++ 应用程序以正确处理字符串的建议,这似乎不可行。对字符串执行此操作的不仅仅是一个应用程序。实际上,我的公司中有很多这样的应用程序需要我处理,这需要大量的人力和时间,而这根本不是可用的。但是,如果我要走这条路,sean e 的想法可能是最好的选择..

@Remy Lebeau:我想一针见血,我会尝试您提出的解决方案并报告回来.. :) 我想您的解决方案需要注意的是 Default 编码具有在 C# 应用程序环境中与创建文件的 C++ 应用程序环境相同,这当然是有道理的,因为它必须使用相同的代码页..

@Jeff Johnson:我没有将文件名从 C++ 应用程序粘贴到 C# 应用程序。我正在调用 OpenFileDialog.ShowDialog() 并在 DialogResult.OK 上获取 OpenFileDialog.FileNames 。我确实尝试使用编码.UTF8.GetBytes(),但就像 Remy Lebeau 指出的那样,它不起作用,因为原始的 UTF8 字节丢失了..

@everyone else: 谢谢你的想法.. :)

克雷布

更新

@Remy Lebeau:你的想法很完美!只要 C++ 应用程序的环境与 C# 应用程序的环境相同(非 Unicode 程序的语言环境相同),我就能检索到正确的文本.. :)

现在我有更多的问题..哈哈..有没有办法确定字符串的编码?该代码现在适用于被错误解释为 ANSI 字符串的 UTF8 字符串,但会破坏 UCS-2 字符串。我需要能够确定编码并相应地处理每个。 GetEncoding() 似乎没有用.. =/ StreamReader 的 CurrentEncoding 属性也不是(总是说 UTF-8)..

附:我应该在新帖子中打开这个新问题吗?

【问题讨论】:

    标签: c# windows unicode utf-8


    【解决方案1】:

    0x201a 是 Unicode“低单逗号引号”字符。 0x82 是该字符的 Latin-1(ISO-8859-1,Windows 代码页 1252)编码。这意味着文件名的字节被解释为普通的 Ansi 而不是 UTF-8,因此被相应地从 Ansi 解码为 Unicode。这并不奇怪,因为文件系统没有 UTF-8 的概念,而且 Windows 假定非 Unicode 文件名使用操作系统的默认 Ansi 编码。

    要执行您要查找的操作,您需要访问原始 UTF-8 编码字节,以便正确解码它们。您可以尝试的一件事是将 FileName 传递给 System.Text.Encoding.Default 的 GetBytes() 方法(理论上,即使用与解码文件名相同的编码,因此它应该能够生成与原始字节相同),然后将生成的字节传递给 System.Text.Encoding.UTF8 的 GetString() 方法。

    【讨论】:

      【解决方案2】:

      我认为你的问题是在开始:

      我有一个 UTF-8 字符串正在 由非 Unicode 程序解释 在 C++ 中.. 显示的这个文本 不正确,但据我所知, 是完整的,然后被应用为 输出文件名..

      如果您使用非 unicode 程序加载 UTF-8 字符串然后对其进行序列化,它将包含非 unicode 字符。

      你的 C++ 程序有什么方法可以处理 Unicode 吗?

      【讨论】:

        【解决方案3】:

        您能否使用 System.Text 命名空间的成员(例如,UTF8Encoding 类)将 .NET 框架的内部字符串表示形式与包含您选择的编码中的文本的字节数组相互转换?

        【讨论】:

          【解决方案4】:

          如果您确定 C++ 输出正常,那么在您的 C# 应用程序中,您应该使用 .NET encoding class 将其从 UTF-8 转换为 UTF-16,并以 Windows 原生格式使用它。

          如果您可以修改 C++ 应用程序,那可能会更好 - 为 C# 应用程序提供不需要重新编码的输入。其中,UTF8 到 Unicode 的转换可以通过 MultiByteToWideChar 处理,使用 CP_UTF8 作为 CodePage 参数,但它仅在没有为 dwFlags 设置任何标志时才有效(为 dwFlags 指定 0)。整个应用程序不需要是 Unicode。即使它不是编译的 unicode,您也可以选择性地使用 Unicode API。

          【讨论】:

            【解决方案5】:

            回答您的问题“有没有办法将文件名视为 utf-8?”试试这个代码:

                List<byte[]> utf8FileNames = new List<byte[]>();
                foreach (string fileName in openFileDialog1.FileNames)
                {
                    utf8FileNames.Add(Encoding.UTF8.GetBytes(fileName));
                }
                // Each byte array in utf8FileNames is a sequence of utf-8 bytes matching each file name chosen
            

            从打开文件对话框中获取文件名后,您将如何处理它们?你能发布那个代码吗?

            【讨论】:

            • 那行不通。当对话框填写其 FileNames 属性时,原始 UTF-8 字节会丢失。由于生成的字符串一开始没有被正确解码,因此将它们传递给 UTF8.GetBytes() 将不会产生与原始 UTF-8 文件名相同的字节。
            • 您是否将文件名从 C++ 应用程序粘贴到 C# 应用程序中?
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2023-04-03
            • 2011-11-27
            • 2011-06-10
            • 1970-01-01
            • 1970-01-01
            • 2011-02-20
            • 1970-01-01
            相关资源
            最近更新 更多