4

次のコードを使用して、ftp サーバーにファイルを作成しようとしています (ここでは、UseBinary オプション true と false も試しました)。

string username = "name";
string password = "password";
string remotefolder = "ftp://ftp.myhost.gr/public_html/test/";
string remoteFileName = "δοκιμαστικό αρχείοüß-äCopy.txt";
string localFile = @"C:\test\δοκιμαστικό αρχείο - Copy.txt";
String ftpname = "ftp://ftp.myhost.gr/public_html/test" + @"/" + Uri.EscapeUriString(Program.remoteFileName);


FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpname);
request.Proxy = null;
request.Credentials = new NetworkCredential(username, password);


request.UsePassive = true;
request.KeepAlive = true;
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UseBinary = true;
//request.UseBinary = false;

 byte[] content = System.IO.File.ReadAllBytes(localFile);
 byte[] fileContents = new Byte[content.Length];

 Array.Copy(content, 0, fileContents, 0, content.Length);

 using (Stream uploadStream = request.GetRequestStream())
 {
     int contentLength = fileContents.Length;
     uploadStream.Write(fileContents, 0, contentLength);
 }

 FtpWebResponse response = (FtpWebResponse)request.GetResponse();
 Console.WriteLine(response.ExitMessage);

問題は、ftp サーバーのファイルが、英語、ギリシャ語、ドイツ語の文字を含む要求した名前を取得しないことです --> "δοκιμαστικό αρχείοüß-äCopy.txt

1) 私はそれで何ができますか?

地域の設定を変更すると、いくつかの改善があります->非Unicodeプログラムの現在の言語をギリシャ語に変更しますが、それでもドイツ語の文字が恋しいです。

2) ac# プログラムがこの設定に依存するのはなぜですか? この設定からの依存を避けるために従うべき特別な方法論はありますか?

エンコーディングの悪夢が再び発生しました:(

4

2 に答える 2

9

文字列を UTF8 としてエンコードし、ファイル名として FTP サーバーに送信するだけでは十分ではありません。過去には、すべての FTP サーバーは ASCII のみを理解していましたが、現在では下位互換性を維持するために (たとえ Unicode を認識していても)、起動時にすべてのファイル名も ASCII として扱います。

それをすべて機能させるには、あなた(あなたのプログラム)はまずあなたのサーバーの能力をチェックしなければなりません。サーバーは、クライアントが接続した後に機能を送信します。この場合、FEAT UTF8を確認する必要があります。サーバーがそれを送信する場合、それは UTF8 を理解していることを意味します。それにもかかわらず、たとえそれが理解できたとしても、今後はUTF8でエンコードされたファイル名を送信することを明示的に伝える必要があり、これはプログラムに欠けているものです(サーバーはあなたが述べたようにutf8をサポートしているため)。

クライアントは、次のOPTS UTF8 ONを FTP サーバーに送信する必要があります。それを送信した後、UTF8を使用するか、UTF8っぽい(いわば)サーバーに話すことができます。

詳細はこちらファイル転送プロトコルの国際化

于 2013-11-11T10:06:37.827 に答える
4

あなたのコードの変更で:

string localFile = @"C:\test\δοκιμαστικό αρχείο - Copy.txt";
String ftpname = "ftp://ftp.myhost.gr/public_html/test" + @"/" + Uri.EscapeUriString(Program.remoteFileName);

FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpname);

に:

string remoteFileName = "δοκιμαστικό αρχείο - Copy.txt";
String ftpname = "ftp://ftp.myhost.gr/public_html/test" + @"/" + remoteFileName;

var escapedUriString = Uri.EscapeUriString(Encoding.UTF8.GetString(Encoding.ASCII.GetBytes(ftpname)));
var request = (FtpWebRequest)WebRequest.Create(escapedUriString);

EscapeUriStringの入力パラメーターは RFC 2396 仕様に従ってエスケープされるため、これを行う必要があります。

RFC 2396標準には次のように記載されています。

新しい URI スキームが Universal Character Set [UCS] の文字で構成されるテキスト データを表すコンポーネントを定義する場合、データは最初に UTF-8 文字エンコーディング [STD63] に従ってオクテットとしてエンコードする必要があります。次に、予約されていないセットの文字に対応しないオクテットのみをパーセントでエンコードする必要があります。

したがって、上記のコード変更により、この文字列は強制的に UTF-8 形式で入力されます。

に関して:

  1. ac# プログラムがこの設定に依存するのはなぜですか? この設定からの依存を避けるために従うべき特別な方法論はありますか?

Uri.EscapeUriStringRFC 2396 仕様に準拠した入力が必要なため、理解できる形式でデータを渡す必要があります。

于 2013-11-04T17:52:41.290 に答える