2009-06-19 84 views
1

C#这里的问题..打开文件对话框的文件名作为UTF8

我有一个是由非Unicode程序用C++解释一个UTF8字符串..这是显示不正确,但据我可以在这个文本告诉,完好无损,然后作为输出文件名应用。

无论如何,在一个C#项目中,我试图用一个System.Windows.Forms.OpenFileDialog对象打开此文件。我从这个对象的.FileNames []得到的文件名是Unicode(UCS-2)。但是,这个字符串被误解了。例如,如果原始字符串是0xe3 0x81 0x82,FileName [] .ToCharArray()显示它现在是0x00e3 0x0081 0x201a ....它可能看起来像OpenFileDialog对象只填充它,但它不是..在OpenFileDialog产生的第三个字符,它是不同的,我不知道这个字节发生了什么..

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

我不认为这是相关的,但如果你需要知道,字符串是日语..

感谢,

克雷布斯

UPDATE

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

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

@Remy Lebeau:我觉得在脑海中碰到钉子,我会尝试你提出的解决方案并回报..: )我想你的解决方案的警告是,在C#应用程序环境中,编码必须与创建该文件的C++应用程序环境相同,这当然是有意义的,因为它必须使用相同的代码页。 。

@Jeff Johnson:我不是将C++应用程序的文件名粘贴到C#应用程序中。我调用OpenFileDialog.ShowDialog()并获取DialogResult.OK上的OpenFileDialog.FileNames ..我尝试了使用Encoding.UTF8.GetBytes(),但像雷米Lebeau点泰德出来,它不会工作,因为原来的UTF8字节丢失..

@everyone其他:谢谢你的想法.. :)

克雷布斯

UPDATE

@雷米Lebeau:你的想法完美的工作!只要C++应用程序的环境与C#应用程序的环境相同(非Unicode程序的相同区域设置),我就可以检索正确的文本。:)

现在我有更多的问题..哈哈..有没有什么办法来确定一个字符串的编码?该代码现在适用于被错误解释为ANSI字符串的UTF8字符串,但将UCS-2字符串拧紧。我需要能够确定编码和相应的处理。 GetEncoding()似乎没有用.. = /并且StreamReader的CurrentEncoding属性(始终表示UTF-8)也不是。

P.S.我应该在新帖子中打开这个新问题吗?

回答

2

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()方法。

1

我觉得你的问题是在开始时:

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

如果加载一个UTF-8字符串,其非Unicode程序,然后将其序列化,它将包含非Unicode字符。

有没有什么办法可以让你的C++程序处理Unicode?

1

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

1

如果您确定C++输出没问题,那么在您的C#应用​​程序中,您应该使用.NET encoding class将其从UTF-8转换为UTF-16,并且仅以Windows本机格式使用它。

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

1

回答你的问题“有没有办法将文件名视为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 

你使用的文件名,一旦你已经从打开文件对话框让他们做什么?你可以发布该代码吗?

+0

这是行不通的。当对话框填充其FileNames属性时,原始的UTF-8字节会丢失。由于结果字符串没有被正确解码,因此将它们传递给UTF8.GetBytes()将不会生成与原始UTF-8文件名相同的字节。 – 2009-06-19 22:00:30

+0

您是否将来自C++应用程序的文件名粘贴到C#应用程序中? – jjxtra 2009-06-19 22:12:16