简体   繁体   中英

Uploading two times a file to FTP

I need to upload the same file (attached by the way to a WebForm) to an FTP server in two different directories.

The problem is that the first upload is OK, but the second is not OK - the file is missing or if present has 0 length (is empty)..

Here is my code (my FtpManager class):

public void UploadFile(HttpPostedFileBase fileToUpload, string ftpDirPath)
{
    try
    {
        var uploadUrl = string.Format("ftp://{0}//{1}", serverIp, ftpDirPath);
        var uploadFilename = fileToUpload.FileName;
        Stream streamObj = fileToUpload.InputStream;
        byte[] buffer = new byte[fileToUpload.ContentLength];
        streamObj.Read(buffer, 0, buffer.Length);
        streamObj.Close();
        streamObj = null;
        string ftpurl = String.Format("{0}/{1}", uploadUrl, uploadFilename);
        ftpRequest = FtpWebRequest.Create(ftpurl) as FtpWebRequest;
        ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
        ftpRequest.Timeout = 1000000;
        ftpRequest.UseBinary = true;
        ftpRequest.UsePassive = true;
        ftpRequest.KeepAlive = true;
        ftpRequest.Credentials = new NetworkCredential(username, password);
        Stream requestStream = ftpRequest.GetRequestStream();
        requestStream.Write(buffer, 0, buffer.Length);
        requestStream.Flush();
        requestStream.Close();
        requestStream = null;

        FtpWebResponse uploadResponse = (FtpWebResponse)ftpRequest.GetResponse();
        uploadResponse.Close();

        ftpRequest = null;

    }
    catch
    {
        throw;
    }
}

I use it like this:

string serverIp = SERVER;
string user = FTP_USER;
string pass = FTP_PASSWORD;
string ftpDir1 = "var/www/rrhh/_lib/tmp";
string ftpDir2 = "var/www/rrhh/docs";

var ftpManager = new FtpManager(serverIp, user, pass);

ftpManager.UploadFile(file, ftpDir1);
ftpManager.UploadFile(file, ftpDir2);

So my question is my the second time my method works (does not throw exceptions), but however does not (upload correctly the file)?

PS.

Analysing the result:

FtpWebResponse uploadResponse = (FtpWebResponse)ftpRequest.GetResponse();
response = "Status Code: {0}; Description: {1}".Fill(
    uploadResponse.StatusCode,
    uploadResponse.StatusDescription);
uploadResponse.Close();

First Upload

Status Code: ClosingData; Description: 226 File receive OK.

Second Upload:

Status Code: ClosingData; Description: 226 File receive OK.

After reading from your InputStream , you are at its end and the second time you get an empty byte array. Use streamObj.Position = 0 before the call to streamObj.Read() to go back to the start of the InputStream .

Might I suggest saving the file to a temporary directory, eg. using:

var fileName = System.IO.Path.GetTempFileName();
file.SaveAs(fileName);

[...]
ftpManager.UploadFile(fileName, ftpDir1);
ftpManager.UploadFile(fileName, ftpDir2);
System.IO.File.Delete(fileName);

Then change your UploadFile method to use a filename instead:

public void UploadFile(string fileToUpload, string ftpDirPath)
[...]
Stream streamObj = File.OpenRead(fileToUpload);
byte[] buffer = new byte[streamObj.Length];
[...]

Modified like this (added bool closeStream ):

public void UploadFile(HttpPostedFileBase fileToUpload, 
                       string ftpDirPath, bool closeStream)
{
    try
    {
        var uploadFilename = fileToUpload.FileName;
        Stream streamObj = fileToUpload.InputStream;
        byte[] buffer = new byte[fileToUpload.ContentLength];
        streamObj.Position = 0;
        streamObj.Read(buffer, 0, buffer.Length);
        if (closeStream)
        {
            streamObj.Close();
            streamObj = null;
        }
        ...

usage:

ftpManager.UploadFile(file, ftpDir1, false);
ftpManager.UploadFile(file, ftpDir2, true);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM