上传到 FTP 并使用 FtpWebRequest 下载回来后,存档或图像已损坏

Archive or image is corrupted after uploading to FTP and downloading back with FtpWebRequest

我有两个方法:

  1. 上传文件到 FTP 服务器
  2. 从服务器下载文件。

一切都与文本或 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);
}

有关完整代码,请参阅