6

Spolskyによると、私は自分自身を開発者と呼ぶことはできないので、この質問の背後には多くの恥が潜んでいます...

シナリオ: C# アプリケーションから、SQL データベースから文字列値を取得し、それをディレクトリの名前として使用したいと考えています。DB からの文字列値を使用して現在のディレクトリを設定したい安全な (SSL) FTP サーバーがあります。
問題:「特殊な」文字を含む文字列値にヒットするまで、すべて正常に動作しています。ディレクトリ名を正しくエンコードして FTP サーバーを満たすことができないようです。

以下のコード例

  • 例として「特殊」文字 é を使用します
  • ftps 通信用の外部アプリケーションとして WinSCP を使用します。
  • プロセス "_winscp" をセットアップするために必要なすべてのコードを示しているわけではありません。
  • プロセス標準入力に書き込むことにより、コマンドを WinSCP exe に送信します。
  • 簡単にするために、DB から情報を取得するのではなく、単に文字列を宣言します (ただし、DB からの値が宣言された文字列と同じであることを確認するために .Equals を実行しました)。
  • 異なる文字列エンコーディングを使用して、FTP サーバーに現在のディレクトリを設定しようと 3 回試みますが、すべて失敗します。
  • 手作りのバイト配列から作成された文字列を使用してディレクトリを設定しようとします-これは機能します

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) + "\"");

UTF8 エンコーディングは é を 101 (10 進数) に変更しますが、FTP サーバーはそれを好みません。

ASCII エンコーディングは é を 63 (10 進数) に変更しますが、FTP サーバーはそれを好みません。

é を値 130 (10 進数) として表すと、FTP サーバーは満足しますが、これを行うメソッドが見つからないことを除きます (明示的なバイトから文字列を手動で構築する必要がありました)。

é を 130 としてエンコードし、FTP サーバーを満足させ、開発者が理解すべき唯一のことを説明して、最終的に私をレベル 1 開発者に昇格させるために、文字列に何をすべきか知っている人はいますか?

4

2 に答える 2

4

130 は ASCII ではありません (ASCII は 7 ビットのみです。Encoding.ASCII のドキュメントを参照してください。そのため、「é」を通常の「?」に変更します)。UTF-8 は実際には文字を2 バイト(10 進数: 195 & 169) にエンコードしますが、コードポイントは保持します。

Latin (CP 1252)などのコードページを明示的に使用します。反対側が何であれ一致する必要があります。以下のように、出力に「130」がないため、必要なエンコーディングではありません:-)しかし、同じことが当てはまります。特定のコードページのエンコーディングを使用します。

編集: Hans Passant がコメントで説明したように、ここで使用するコード ページは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を参照してください。

ハッピーコーディング。

ところで。アーティストの良い選択 -- 意図的だった場合:p

于 2011-02-25T06:47:45.033 に答える
1

ここでの問題は、すべての .NET 文字列が Unicode であることだと思います。.NET 文字列には「私が何をエンコードしているか」というものはありません。したがってEncoding.ASCII.GetString(buffer)、ASCII の「文字列」を Unicode に変換して使用します。

Process.StandardInput のエンコーディングを変更することで問題を解決する必要があると思います。そうすれば、WinSCP 内で正しいエンコーディングが得られます。

また

Encoding.DefaultUTF8でもASCIIでもないと確信しているので、何が何であるかを確認する必要があります。

于 2011-02-25T06:41:09.647 に答える