12
votes

I'm writing a program that uses an ftp server with credentials. I'm trying to retrieve the directory list from the server but when I get to the line:

string line = reader.ReadLine();

the string that I get contains only : "Can't open \"host:/lib1\"."

If I try to get another line, the next exception is thrown: The remote server returned an error: (550) File unavailable (e.g., file not found, no access).

I know for sure (using another ftp application) that 'lib1' directory exists on the ftp server and my credentials (username and password) are correct.

Here is my code:

 public class FTPClient
{
    public string UserName { get; set; }
    public string Password { get; set; }
    public string IpAddress { get; set; }
    public int Port { get; set; }

    public FTPClient(string _userName, string _password, string _address, int _port)
    {
        UserName = _userName;
        Password = _password;
        IpAddress = _address;
        Port = _port;
    }

    public void GetDirectoriesList(string _path)
    {           
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri("ftp://" + 
        IpAddress + _path));
        request.UseBinary = true;
        request.Method = WebRequestMethods.Ftp.ListDirectory;
        request.Credentials = new NetworkCredential(UserName, Password);

        FtpWebResponse response = (FtpWebResponse)request.GetResponse();
        Stream responseStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(responseStream);

        string line = reader.ReadLine();
        while (line!=null)
        {
            ... //do something with line
            line = reader.ReadLine();
        }
        ...
        reader.Close();
        response.Close();


    }

And I use it as follows:

FTPClient ftpClient = new FTPClient("user1", "pass1", "192.168.2.110", 21);

        string dirList = ftpClient.GetDirectoriesList("/lib1");

Can anyone spot the problem?

2
A more general question about getting a directory listing from an FTP server in C#: stackoverflow.com/questions/3298922/…Jon Schneider
use custom validation of the certificate,see stackoverflow.com/questions/5109752/…syed
This question is pretty unclear - are you simply asking for a way to connect to an FTP server with credentials, or for us to debug this specific code? Are you open to solutions using libraries, such as FluentFTP? Does reading the first line give you an incorrect result (what you say in your second sentence) or throw an exception (what you imply when you say that the second ReadLine call throws another exception)? There's too much unfixably wrong here; I'm voting to close.Mark Amery
I'm voting to close this question as off-topic because it isn't exactly clear what is going wrong and seems like it may be something very specific to the OPs environment or the server they are connecting to. As such, it would be hard to answer definitively and most likely would not be a help to someone else in the future.pstrjds
The only thing I don't see in your code is where you append the port number to your IP address in the request Uri? I'm not 100% certain that is the issue, but just by looking at what you've posted, part of the error you got back looked like this: "host:/lib1" which makes it appear the host and colon were in your Uri but no port number is shown after the colon. So maybe the issue is simply the format of your request Uri?Ben Bloodworth

2 Answers

16
votes

My solution:

public string[] GetDirectory()
{
    StringBuilder result = new StringBuilder();
    FtpWebRequest requestDir = (FtpWebRequest)WebRequest.Create("ftp://urserverip/");
    requestDir.Method = WebRequestMethods.Ftp.ListDirectory;
    requestDir.Credentials = new NetworkCredential("username", "password");
    FtpWebResponse responseDir = (FtpWebResponse)requestDir.GetResponse();
    StreamReader readerDir  = new StreamReader(responseDir.GetResponseStream());

    string line = readerDir.ReadLine();
    while (line != null)
    {
        result.Append(line);
        result.Append("\n");
        line = readerDir.ReadLine();
    }

    result.Remove(result.ToString().LastIndexOf('\n'), 1);
    responseDir.Close(); 
    return result.ToString().Split('\n');
}
10
votes

Some refinements to Abdul Waheed's answer:

  • Added using blocks to clean up the FtpWebResponse and StreamReader objects;
  • Reduced string manipulation:

    private static string[] GetDirectoryListing()
    {
        FtpWebRequest directoryListRequest = (FtpWebRequest)WebRequest.Create("ftp://urserverip/");
        directoryListRequest.Method = WebRequestMethods.Ftp.ListDirectory;
        directoryListRequest.Credentials = new NetworkCredential("username", "password");
    
        using (FtpWebResponse directoryListResponse = (FtpWebResponse)directoryListRequest.GetResponse())
        {
            using (StreamReader directoryListResponseReader = new StreamReader(directoryListResponse.GetResponseStream()))
            {
                string responseString = directoryListResponseReader.ReadToEnd();
                string[] results = responseString.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
                return results;
            }
        }
    }