使用国际字符读取FTP文件

时间:2015-09-09 12:10:39

标签: c# .net ftp ftpwebrequest ftpwebresponse

我正在使用以下代码下载FTP位置文件。它适用于所有文件,除非文件名包含国际字符。

我已经学会了URI格式,这是不允许的,但如果在上述位置有现有文件,如何下载。

为了测试我在IIS下设置了本地FTP服务器,如下所示。

http://www.online-tech-tips.com/computer-tips/setup-ftp-server-in-windows-iis/

string mat_address = "ftp://localhost/";
StringBuilder result = new StringBuilder();
FtpWebRequest ftp = (FtpWebRequest)WebRequest.Create(mat_address);

ftp.Credentials = new NetworkCredential("userid", "Password");
ftp.Method = WebRequestMethods.Ftp.ListDirectory;

string[] downloadfile = null;
using (FtpWebResponse response = (FtpWebResponse)ftp.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default, true))
{
    downloadfile = reader.ReadToEnd().Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
}

foreach (string d in downloadfile)
{
    if (d.Contains("d"))
    {
        string temp = mat_address + HttpUtility.UrlPathEncode(d);
        FtpWebRequest ftp2 = (FtpWebRequest)WebRequest.Create(temp);

        ftp2.Credentials = new NetworkCredential("userid", "Password");

        ftp2.Method = WebRequestMethods.Ftp.GetDateTimestamp;

        ftp2.UseBinary = true;

        ftp2.Proxy = null;
        ftp2.KeepAlive = false;
        ftp2.UsePassive = false;

        FtpWebResponse response2 = ftp2.GetResponse() as FtpWebResponse;
        DateTime temp1 = response2.LastModified.Date;
        if (temp1 > DateTime.Now.AddDays(-10))
        {
           // Some extra work
        }
    }
}

我收到错误

  

远程服务器返回错误:(550)文件不可用(例如,找不到文件,无法访问)。

File unavailable error

以下是我的FTP根文件夹,其中有问题的文件名为diá.png

enter image description here

我使用C#进行编码,使用Visual Studio 2013进行开发。怎么会有人帮忙。

更新问题: 编码更改为UTF8。 使用本地主机一切正常。但是当使用来自德国和瑞典等国际域的FTP服务器时。名称如下所示。

我收到以下一行的错误。

FtpWebResponse response2 = ftp2.GetResponse() as FtpWebResponse;

文件名的十六进制值:建议包括Martin。谢谢 31,30,31,33,36,2D,49,43,4F,4D,20,50,4A,C4,54,54,45,52,59,44,20,70,69,63,74,20,37‌​,38,78,31,31,38,20,61,6E,6E,69,2D,76,65,72,73,61,72,69,75,73,20,5B,77,31,33,32,31‌​,20,78,20,68,39,32,31,5D,20,6D,6D,20,44,49,46,46,55,53,45,2E,50,4E,47,

2 个答案:

答案 0 :(得分:4)

大多数FTP服务器应使用UTF-8编码。您的本地(IIS)服务器也是如此。

因此,在解析目录列表时需要使用Encoding.UTF8

虽然您的真实/生产服务器似乎在某种程度上被破坏了。看起来它使用Windows-1252编码进行目录列表。然而它声称(并且似乎需要)UTF-8编码用于命令。这显然(并且合理地)混淆了FileZilla。但我没有看到,为什么它不适用于FtpWebRequest,因为它应该使用UTF-8(因为服务器肯定响应OPTS utf8 on命令),并且您已尝试显式使用Windows -1252编码,解析列表时。

无论如何,当您在聊天中发现WinSCP有效时,您可以尝试使用WinSCP .NET assembly。它还可以使您的代码更简单:

SessionOptions sessionOptions = new SessionOptions();
sessionOptions.Protocol = Protocol.Ftp;
sessionOptions.HostName = "hostname";
sessionOptions.UserName = "username";
sessionOptions.Password = "password";

using (Session session = new Session())
{
    session.Open(sessionOptions);

    foreach (RemoteFileInfo fileInfo in session.ListDirectory("/textures").Files)
    {
        if (fileInfo.Name.Contains("d"))
        {
            if (fileInfo.LastWriteTime > DateTime.Now.AddDays(-10))
            {
                string sourcePath =
                    RemotePath.EscapeFileMask("/textures/" + fileInfo.Name);
                session.GetFiles(sourcePath, @"c:\local\path\").Check();
            }
        }
    }
}

或者更简单,使用file mask with time constraint

SessionOptions sessionOptions = new SessionOptions();
sessionOptions.Protocol = Protocol.Ftp;
sessionOptions.HostName = "hostname";
sessionOptions.UserName = "username";
sessionOptions.Password = "password";

using (Session session = new Session())
{
    session.Open(sessionOptions);

    session.GetFiles("/textures/*d*>=10D", @"c:\local\path\").Check();
}

另请参阅WinSCP示例How do I transfer new/modified files only?

答案 1 :(得分:0)

我会说,你必须转换收到的文件名的编码以匹配本地文件系统的需要。你能发布你修改的文件名吗?我想你得到一个包含一些非法字符的excaped字符串......