将文件上传两次到 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);
我需要将相同的文件(顺便附加到 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);