2009-06-19 83 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