【问题标题】:Ftp create a filename with utf-8 chars such as greek, german etcFtp 创建带有 utf-8 字符的文件名,例如希腊语、德语等
【发布时间】:2013-11-12 16:49:09
【问题描述】:

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

编码噩梦再次出现:(

【问题讨论】:

  • “问题是我的 ftp 服务器上的文件没有得到我请求的名称” FTP 协议是否支持 Unicode?你的服务器软件呢?
  • 我认为不是。但是因为我可以从 cpanel 完成,最有趣的是从 filezilla (使用强制 utf-8 选项),那么我认为我应该能够通过 C# 完成它..
  • 您使用的是什么 FTP-Server 软件?
  • 好吧,我不拥有服务器。我唯一知道的是它是 Linux 操作系统
  • 您是否尝试更改编码,例如How to Answer[1] [1]:stackoverflow.com/questions/3369863/…

标签: c# encoding utf-8 ftp


【解决方案1】:

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

要使这一切正常运行,您(您的程序)必须首先检查您的服务器的能力。服务器在客户端连接后发送其功能 - 在您的情况下,您必须检查 FEAT UTF8。如果您的服务器发送它 - 这意味着它理解 UTF8。尽管如此 - 即使它理解它 - 你必须明确告诉它,从现在开始你将发送你的文件名 UTF8 编码,现在它是你的程序缺少的东西(因为你的服务器支持你所说的 utf8)。

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

阅读这里了解详情Internationalization of the File Transfer Protocol

【讨论】:

    【解决方案2】:

    在您的代码更改中:

    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 格式输入。

    关于:

    1. 为什么 c# 程序依赖于这个设置?有没有特别的 我应该遵循的方法,以避免依赖于此 设置?

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

    【讨论】:

    • 这不起作用,但感谢您的回答。我会进一步搜索。我投了赞成票,但不确定这是解决方案
    • 只是为了仔细检查,我假设 Program.remoteFileName 和 remoteFileName 是一样的?
    • 是的 remoteFileName 与 Program.remoteFileName 是完全相同的对象
    • 我已经更新了我的答案。我只是部分转义了传递给 WebRequest.Create 的字符串。我已经更新了我的答案,以确保传递给 WebRequest.Create 的整个字符串都被转义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-14
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    • 2017-10-06
    • 2022-07-06
    • 1970-01-01
    相关资源
    最近更新 更多