将文件上传两次到 FTP

Uploading two times a file to FTP

我需要将相同的文件(顺便附加到 WebForm)上传到两个不同目录中的 FTP 服务器。

问题是第一次上传正常,但第二次上传不正常 - 文件丢失或如果存在则长度为 0(为空)..

这是我的代码(我的 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;
    }
}

我是这样使用的:

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);

所以我的问题是我的方法第二次有效(不抛出异常),但没有(正确上传文件)?

PS.

分析结果:

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

第一次上传

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

第二次上传:

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

从您的 InputStream 读取后,您已经到了结尾,第二次您得到一个空字节数组。在调用 streamObj.Read() 之前使用 streamObj.Position = 0 返回到 InputStream.

的开头

我建议将文件保存到一个临时目录,例如。使用:

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

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

然后将您的 UploadFile 方法改为使用文件名:

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

这样修改(添加了 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;
        }
        ...

用法:

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