简体   繁体   English

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

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

I have two methods: 我有两种方法:

  1. Uploads files to the FTP Server 将文件上传到FTP服务器
  2. Downloads Files from the Server. 从服务器下载文件。

Everything works perfectly with text or xml files. 一切都与文本或xml文件完美配合。 But when I'm trying to upload and then download an archive or an image I get the "windows cannot open the folder. the compressed zip file is invalid" error for the archives and almost the same for the images. 但是,当我尝试上载然后下载档案或图像时,档案和与图像几乎都出现“ Windows无法打开文件夹。压缩的zip文件无效”错误。 What may be the problem? 可能是什么问题?

Here is the listing of my methods: 这是我的方法清单:

Upload: 上载:

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

Download: 下载:

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

You are uploading a binary file (a bitmap image) as if it were a text file in UTF-8 encoding: 您正在上传二进制文件(位图图像​​),就好像它是采用UTF-8编码的文本文件一样:

byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());

That naturally corrupts the file. 这自然会损坏文件。

You have to transfer binary files exactly as they are, bit by bit. 您必须完全按原样传输二进制文件。

Moreover your technique is quite inefficient for potentially large image files. 此外,您的技术对于可能很大的图像文件来说效率很低。 You keep whole file in memory at least twice. 您将整个文件保存在内存中至少两次。

The code, that you need, is actually much simpler than yours: 您所需的代码实际上比您的代码简单得多:

using (Stream fileStream = File.OpenRead(FilePath + FileName)
using (Stream ftpStream = request.GetRequestStream())
{
    fileStream.CopyTo(ftpStream);
}

Your download code is ok, but again, it can be simplified to: 您的下载代码可以,但是同样,可以将其简化为:

using (Stream ftpStream = request.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(Destination))
{
    ftpStream.CopyTo(fileStream);
}

For a full code, see Upload and download a binary file to/from FTP server in C#/.NET . 有关完整代码,请参见C#/。NET中的FTP服务器上载二进制文件或从FTP服务器下载二进制文件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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