上传到 FTP 并使用 FtpWebRequest 下载回来后,存档或图像已损坏
Archive or image is corrupted after uploading to FTP and downloading back with FtpWebRequest
我有两个方法:
- 上传文件到 FTP 服务器
- 从服务器下载文件。
一切都与文本或 xml 文件完美配合。但是,当我尝试上传然后下载档案或图像时,我收到档案的 "windows cannot open the folder. the compressed zip file is invalid" 错误,图像几乎相同。可能是什么问题?
这是我的方法列表:
上传:
private string Upload(string Login, string Password, string FilePath, string FileName, string uuid, string FTPDir)
{
string CreateDirectory = CreateFTPDirectory(Login, Password, uuid, FTPDir);
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(@"ftp://" + FTPDir + uuid + "/" + FileName);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UseBinary = true;
StreamReader sourceStream = new StreamReader(FilePath + FileName);
byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;
using (Stream S = request.GetRequestStream())
{
S.Write(fileContents, 0, fileContents.Length);
}
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
return response.StatusDescription;
}
下载:
private string Download(string Login, string Password, string FileName, string uuid, string FTPDir, string Destination)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://" + FTPDir + uuid + "/" + FileName);
request.UseBinary = true;
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = new NetworkCredential(Login, Password);
byte[] buffer = new byte[1024];
using (var response = (FtpWebResponse)request.GetResponse())
{
using (var stream = response.GetResponseStream())
{
using (var fs = new FileStream(Destination, FileMode.OpenOrCreate))
{
int readCount = stream.Read(buffer, 0, 1024);
while (readCount > 0)
{
fs.Write(buffer, 0, readCount);
readCount = stream.Read(buffer, 0, 1024);
}
}
return response.StatusDescription;
}
}
}
您上传的二进制文件(位图图像)就像 UTF-8 编码的文本文件一样:
byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
这自然会损坏文件。
您必须按原样一点一点地传输二进制文件。
此外,对于可能较大的图像文件,您的技术效率很低。您至少将整个文件保存在内存中两次。
您需要的代码实际上比您的简单得多:
using (Stream fileStream = File.OpenRead(FilePath + FileName)
using (Stream ftpStream = request.GetRequestStream())
{
fileStream.CopyTo(ftpStream);
}
你的下载代码没问题,不过还是可以简化为:
using (Stream ftpStream = request.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(Destination))
{
ftpStream.CopyTo(fileStream);
}
有关完整代码,请参阅 。
我有两个方法:
- 上传文件到 FTP 服务器
- 从服务器下载文件。
一切都与文本或 xml 文件完美配合。但是,当我尝试上传然后下载档案或图像时,我收到档案的 "windows cannot open the folder. the compressed zip file is invalid" 错误,图像几乎相同。可能是什么问题?
这是我的方法列表:
上传:
private string Upload(string Login, string Password, string FilePath, string FileName, string uuid, string FTPDir)
{
string CreateDirectory = CreateFTPDirectory(Login, Password, uuid, FTPDir);
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(@"ftp://" + FTPDir + uuid + "/" + FileName);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UseBinary = true;
StreamReader sourceStream = new StreamReader(FilePath + FileName);
byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;
using (Stream S = request.GetRequestStream())
{
S.Write(fileContents, 0, fileContents.Length);
}
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
return response.StatusDescription;
}
下载:
private string Download(string Login, string Password, string FileName, string uuid, string FTPDir, string Destination)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://" + FTPDir + uuid + "/" + FileName);
request.UseBinary = true;
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = new NetworkCredential(Login, Password);
byte[] buffer = new byte[1024];
using (var response = (FtpWebResponse)request.GetResponse())
{
using (var stream = response.GetResponseStream())
{
using (var fs = new FileStream(Destination, FileMode.OpenOrCreate))
{
int readCount = stream.Read(buffer, 0, 1024);
while (readCount > 0)
{
fs.Write(buffer, 0, readCount);
readCount = stream.Read(buffer, 0, 1024);
}
}
return response.StatusDescription;
}
}
}
您上传的二进制文件(位图图像)就像 UTF-8 编码的文本文件一样:
byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
这自然会损坏文件。
您必须按原样一点一点地传输二进制文件。
此外,对于可能较大的图像文件,您的技术效率很低。您至少将整个文件保存在内存中两次。
您需要的代码实际上比您的简单得多:
using (Stream fileStream = File.OpenRead(FilePath + FileName)
using (Stream ftpStream = request.GetRequestStream())
{
fileStream.CopyTo(ftpStream);
}
你的下载代码没问题,不过还是可以简化为:
using (Stream ftpStream = request.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(Destination))
{
ftpStream.CopyTo(fileStream);
}
有关完整代码,请参阅