Bonjour,

Je suis en train de travailler sur un programme qui permet de télécharger des fichiers depuis un serveur FTP.

Je suis parti d'exemples basiques trouvés dans la documentation de Microsoft.

Voici mon code actuel :
Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
 
using System;
using System.IO;
using System.Net;
using System.Collections.Generic;
using System.Text;
 
namespace FtpClient
{
    public class cFtpClient
    {
        public Uri Address { get; set; }
        public string Login { get; set; }
        public string Password { get; set; }
 
 
        public string[] List()
        {
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(Address);
            request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
            request.Credentials = new NetworkCredential(Login, Password);
            request.UsePassive = true;
            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream);
            string[] ret = reader.ReadToEnd().Split('\n');
            List<string> res = new List<string>();
 
            for (int i = 0, cpt = ret.Length; i < cpt; i++)
            {
                if (ret[i].Length > 67)
                {
                    res.Add(ret[i].Substring(67).Trim());
                }
            }
 
            reader.Close();
            return res.ToArray();
        }
 
        public void Download(string file, string place)
        {
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(string.Format("{0}/{1}", Address.AbsoluteUri, file));
            request.Method = WebRequestMethods.Ftp.DownloadFile;
            request.UseBinary = true;
            request.Credentials = new NetworkCredential(Login, Password);
            request.UsePassive = true;
            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            Stream responseStream = response.GetResponseStream();
            FileStream writer = File.Create(string.Format("{0}{1}", place, file.Replace('\\', '_').Replace('/', '_').Replace('*', '_').Replace(':', '_').Replace('?', '_').Replace('"', '_').Replace('<', '_').Replace('>', '_').Replace('|', '_')));
 
            byte[] chunk = new byte[4096];
            int bytesRead;
            while ((bytesRead = responseStream.Read(chunk, 0, chunk.Length)) > 0)
            {
                writer.Write(chunk, 0, bytesRead);
            }
 
            writer.Close();
        }
    }
}

Les fichiers sont des fichiers de toute petite taille (moins de 1 Ko), au format texte, mais avec un encodage qui m'échappe. Télécharger les fichier en binaire a été la seule méthode que j'ai trouvé pour ne pas les altérer.

Le problème se situe avec des fichiers contenant des caractères interdit sous Windows.
Exemple ci-dessous d'une fenêtre de FileZilla contenant un tel fichier :



J'obtiens alors l'erreur ci-dessous :
Le serveur distant a retourné une erreur*: (550) Fichier non disponible (par exemple, fichier introuvable, accès impossible).
Pourtant, FileZilla arrive à télécharger le fichier, donc c'est qu'il y a bien moyen de le récupérer...

Mais comment ?

Le problème vient de cette ligne :
Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(string.Format("{0}/{1}", Address.AbsoluteUri, file));
La variable "file" contient "1372941762-N\'GUYEN.csv"
Je ne sais pas par quoi remplacer cet anti-slash pour que le serveur FTP l'accepte...