views:

364

answers:

3

I am trying to stream a multiline textbox into a text file on an ftp server. Can someone tell me where I may be going wrong?

private void btnSave_Click(object sender, EventArgs e)
{
    UriBuilder b = new UriBuilder();
    b.Host = "ftp.myserver.com";
    b.UserName = "user";
    b.Password = "pass";
    b.Port = 21;
    b.Path = "/myserver.com/directories/" + selected + ".txt";
    b.Scheme = Uri.UriSchemeFtp;
    Uri g = b.Uri;

    System.Net.FtpWebRequest c = (System.Net.FtpWebRequest)System.Net.FtpWebRequest.Create(g);
    c.Method = System.Net.WebRequestMethods.Ftp.DownloadFile;

    System.Net.FtpWebResponse d = (System.Net.FtpWebResponse)c.GetResponse();

    System.IO.Stream h = d.GetResponseStream;
    System.IO.StreamWriter SW = new System.IO.StreamWriter(h);
    String[] contents = textBox1.Lines.ToArray();
    for (int i = 0; i < contents.Length; i++)
    {
        SW.WriteLine(contents[i]);
    }



    h.Close();
    SW.Close();

    d.Close();
}

The error I am getting is this line:

System.IO.StreamWriter SW = new System.IO.StreamWriter(h);

Stream was not writable.

Any ideas?

+5  A: 

The response stream from an FTP site is data from the site to you. You'd need the request stream... but then you wouldn't want a method of DownloadFile - you're not downloading, you're uploading, so you want the UploadFile method.

Additionally:

  • You're not closing anything if exceptions are thrown: use using blocks for this.
  • It's a bad idea to do network access like this on the UI thread; the UI thread will block (so the whole UI will hang) while the FTP request is happening. Use a background thread instead.
Jon Skeet
When I switch to upload file I get an error with this line:System.IO.Stream h = d.GetResponseStream;Cannot convert method group 'GetResponseStream' to non-delegate type 'System.IO.Stream'. Did you intend to invoke the method?
David
I am now getting an error with this line: System.IO.StreamWriter SW = new System.IO.StreamWriter(h); Stream was not writable...
David
As I said in the answer, you shouldn't be opening the response stream at all - you should be opening the *request* stream.
Jon Skeet
+3  A: 

To upload a file you need to use the FtpWebRequest class.

Quote:

When using an FtpWebRequest object to upload a file to a server, you must write the file content to the request stream obtained by calling the GetRequestStream method or its asynchronous counterparts, the BeginGetRequestStream and EndGetRequestStream methods. You must write to the stream and close the stream before sending the request.

For an example of uploading a file (which you can change to writing stream content as in your example) see here.

Codesleuth
I dont have the option to add getrequest stream - it keeps throwing me errors.
David
@David: "it keeps throwing me errors" isn't very precise... could you give the exact error message?
Jon Skeet
A: 

Taken from MSDN and slightly modified:

public static bool UploadFileOnServer(string fileName, Uri serverUri)
{
    // The URI described by serverUri should use the ftp:// scheme.
    // It contains the name of the file on the server.
    // Example: ftp://contoso.com/someFile.txt. 
    // The fileName parameter identifies the file 
    // to be uploaded to the server.

    if (serverUri.Scheme != Uri.UriSchemeFtp)
    {
        return false;
    }
    // Get the object used to communicate with the server.
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
    request.Method = WebRequestMethods.Ftp.UploadFile;

    StreamReader sourceStream = new StreamReader(fileName);
    byte [] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
    sourceStream.Close();
    request.ContentLength = fileContents.Length;

    // This example assumes the FTP site uses anonymous logon.
    request.Credentials = new NetworkCredential ("anonymous","[email protected]");
    Stream requestStream = request.GetRequestStream();
    requestStream.Write(fileContents, 0, fileContents.Length);
    requestStream.Close();
    FtpWebResponse response = (FtpWebResponse) request.GetResponse();

    Console.WriteLine("Upload status: {0}",response.StatusDescription);

    response.Close();  
    return true;
}
Frank Bollack