2011-02-25 72 views
6

Spolsky我不能稱自己爲開發人員,所以有很多背後的問題恥辱......我需要幫助將C#字符串從一種字符編碼轉換爲另一種字符編碼?

情景:從C#應用程序,我想從一個字符串值SQL數據庫並將其用作目錄的名稱。我有一個安全的(SSL)FTP服務器,我想使用數據庫中的字符串值來設置當前目錄。
問題:一切工作正常,直到我打了一個「特殊」字符的字符串值 - 我似乎無法目錄名稱正確編碼,以滿足FTP服務器。

下面

  • 的代碼示例使用「特殊」的字符é作爲一個例子
  • 使用的WinSCP作爲FTPS通訊科
  • 外部應用程序不顯示所有需要的設置過程中的代碼「_winscp」。
  • 通過寫入過程standardinput
  • 爲簡單起見發送到WinSCP賦予EXE命令,不從DB獲得的信息,而只是聲明瞭一個字符串(但我確實做了.Equals確認從價值DB與聲明的字符串相同
  • 三次嘗試使用不同的字符串編碼設置FTP服務器上的當前目錄 - 所有這些都失敗
  • 嘗試使用創建的字符串設置目錄從手工製作的字節數組 - 其中工程

Process _winscp = new Process(); 
byte[] buffer; 

string nameFromString = "Sinéad O'Connor"; 
_winscp.StandardInput.WriteLine("cd \"" + nameFromString + "\""); 

buffer = Encoding.UTF8.GetBytes(nameFromString); 
_winscp.StandardInput.WriteLine("cd \"" + Encoding.UTF8.GetString(buffer) + "\""); 

buffer = Encoding.ASCII.GetBytes(nameFromString); 
_winscp.StandardInput.WriteLine("cd \"" + Encoding.ASCII.GetString(buffer) + "\""); 

byte[] nameFromBytes = new byte[] { 83, 105, 110, 130, 97, 100, 32, 79, 39, 67, 111, 110, 110, 111, 114 }; 
_winscp.StandardInput.WriteLine("cd \"" + Encoding.Default.GetString(nameFromBytes) + "\""); 

é至101(十進制)UTF8編碼變化,但該FTP服務器不喜歡它。

é到63(十進制)的ASCII編碼變化,但FTP服務器不喜歡它。

當我代表é爲值130(十進制)的FTP服務器是幸福的,但我找不到,會爲我做這個(我不得不手動contruct從明確字節字符串)的方法。

任何人都知道我應該做我的字符串編碼é爲130,使FTP服務器開心,最後通過解釋的唯一一件事情開發商應該瞭解提升我1級開發者?

+2

這winscp進程是問題的一部分,它是一個控制檯模式的應用程序,運行在代碼頁437,舊的IBM PC編碼。其中130確實是é的字符代碼。 StandardInput流通常會自動處理翻譯,但您的代碼非常奇怪。它不能像片段中給出的那樣工作,該過程必須首先啓動。失去winscp,使用System.Net支持FTP。 –

+0

感謝您的信息漢斯。我意識到這段代碼並不工作(我刪除了所有的流程初始化代碼)。我很想使用一些原生的.net FTP支持 - 但它可以支持通過SSL的FTP(即。ftps)嗎? – Handleman

+0

爲了完善未來的開發人員 - 我採納了Hans的建議,並查看了本地.net FTP庫,並且他們可以處理ftps - 所以我很快地切換了代碼,現在不再依賴外部WinSCP應用程序,似乎有沒有編碼問題 - 它只是工作。非常滿意沒有外部應用程序,更簡單的代碼和更好的性能。 – Handleman

回答

4

130不是ASCII(ASCII只有7位 - 見Encoding.ASCII文檔 - 所以它把「é」改成正常的「?「因爲它有什麼好做),UTF-8實際上的字符編碼成兩個字節(十進制:195 & 169),但保留了碼點

使用代碼頁明確,如。因爲從下面看,輸出中沒有「130」,所以......不是你需要的編碼:-)但同樣適用:對特定代碼頁使用編碼。

編輯:漢斯·帕桑特在註釋中說明,代碼頁用在這裏是MS-DOS (CP 437)這將導致預期的效果

// LINQPad -- Encoding is System.Text.Encoding 
var enc = Encoding.GetEncoding(1252); 
string.Join(" ", enc.GetBytes("Sinéad O'Connor")).Dump(); 
// -> 83 105 110 233 97 100 32 79 39 67 111 110 110 111 114 

請參閱:http://msdn.microsoft.com/en-us/goglobal/bb688114瞭解更多信息。

快樂編碼。

Btw。藝術家的好選擇 - 如果它是故意的:p

+0

感謝pst和榮譽給漢斯。對於那些感興趣的我現在的代碼如下所示:string nameFromString =「SinéadO'Connor」; byte [] buffer = Encoding.GetEncoding(437).GetBytes(nameFromString); _winscp.StandardInput.WriteLine(「cd \」「+ Encoding.Default.GetString(buffer)+」\「」); – Handleman

1

我覺得這裏的問題是,所有的.NET字符串爲Unicode。在.NET字符串中沒有「我是什麼編碼」。因此,使用Encoding.ASCII.GetString(buffer),您可以將ASCII字符串轉換爲Unicode。

我認爲你的問題應該通過改變Process.StandardInput的編碼來解決,這樣你就可以在WinSCP中獲得正確的編碼。

OR

你應該檢查什麼Encoding.Default是,因爲我敢肯定它不是UTF8或ASCII。

+0

謝謝Euphoric。我確實找到了設置Process.StandardInput編碼的方法,而且我只嘗試了UTF8,但它似乎沒有幫助(現在在家沒有代碼,將在星期一安裝)。我並不擔心Default編碼,因爲它只是一種將字節數組版本轉換爲字符串進行測試的方法。 – Handleman

+0

@pst:我並不是說字符串根本沒有任何編碼。我的意思是你不能選擇什麼編碼字符串。它總是UTF-16。 @Handleman:好的,現在你可以看到這個「默認」編碼不是UTF-8或ASCII,而是你的區域設置編碼。 – Euphoric