2015-09-09 7 views
0

Я загружаю файл местоположения FTP, используя приведенный ниже код. Он работает для всех файлов, кроме тех случаев, когда имя файла содержит международный символ.Прочитать файл FTP с международными символами

Я узнал в формате URI, так что это запрещено, но как можно скачать, если в указанном месте есть файл.

Для тестирования У меня есть локальный FTP-сервер под IIS, как показано ниже.

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 
     } 
    } 
} 

Я получаю ошибку

The remote server returned an error: (550) File unavailable (e.g., file not found, no access).

File unavailable error

Ниже мой корень FTP папку с проблемного именем файла diá.png

enter image description here

Я использую C# для кодирования и Visual Studio 2013 для разработки. Что-то не так, может кто-то поможет.

Дополнение к вопросу: Изменения в кодировке UTF8. Использование локального хоста все работает нормально. Но при использовании FTP-сервера из международного домена, такого как Германия и Швеция. Имя читается, как показано ниже.

Я получаю сообщение об ошибке ниже.

FtpWebResponse response2 = ftp2.GetResponse() as FtpWebResponse; 

Hex Значение для имени файла: Отдается включает Мартин. Спасибо 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

Большинство 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?

+0

Я обновил мой вопрос. Как вы сказали, кодирование должно быть UTF8, это вызывает у меня проблему и имя файла, которое я собираюсь читать с FTP-сервера, идет не так. Я добавил это как дополнение к исходному вопросу. – Pratik

+0

Так что, возможно, настоящий сервер использует кодировку Ansi. Попробуйте «Encoding.GetEncoding (1252)». Трудно догадаться. Покажите нам шестнадцатеричный дамп потока ответов. –

+0

Хорошо, я проверю. @Martin Как я получу дамп HEX. Это исключение? – Pratik

0

Я бы сказал, вам нужно будет преобразовать кодировку полученного имени файла в соответствии с потребностями вашей локальной файловой системы. Не могли бы вы опубликовать какое имя файла вы вернете? Я думаю, что вы получили строку excpeded, содержащую некоторые незаконные символы ...

Смежные вопросы