Ftp使用utf-8字符创建文件名,例如希腊语,德语等

我正在尝试使用以下代码创建一个文件到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#程序依赖于此设置? 是否有一种特殊的方法我应该遵循以避免这种设置的依赖?

编码噩梦再次出现:(

仅将字符串编码为UTF8并将其作为文件名发送到FTP服务器是不够的。 在过去,所有FTP服务器都只理解ASCII,现在为了保持向后兼容性 – 即使它们是Unicode识别的 – 当它们启动时它们也将所有文件也视为ASCII。

为了使一切顺利,您(您的程序)必须首先检查您的服务器能够做什么。 客户端连接后服务器发送其function – 在您的情况下,您必须检查FEAT UTF8 。 如果你的服务器发送 – 这意味着它理解UTF8。 然而 – 即使它理解它 – 你必须明确告诉它,从现在开始你将发送你的文件名UTF8编码,现在它是你的程序缺乏的东西(因为你的服务器支持utf8,如你所说)。

您的客户端必须向FTP服务器发送以下OPTS UTF8 ON 。 发送之后,您可以使用UTF8或对您的服务器说UTF8-ish(可以这么说)。

请阅读此处了解详细信息文件传输协议的国际化

在您的代码更改中:

 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方案定义表示由通用字符集[UCS]中的字符组成的文本数据的组件时,应首先根据UTF-8字符编码[STD63]将数据编码为八位字节; 那么只有那些与未保留集中的字符不对应的八位字节应该是百分比编码的。

因此,上面显示的代码更改将强制此字符串以UTF-8格式输入。

关于:

2)为什么ac#程序依赖于此设置? 是否有一种特殊的方法我应该遵循以避免这种设置的依赖?

Uri.EscapeUriString需要遵循RFC 2396规范的输入,因此需要以它将理解的格式传递数据。