C# - 如何使用FTP上传更大的文件?

时间:2018-03-16 13:52:53

标签: c# file-upload ftp ftpwebrequest

当我上传大约12kb及以下的文件时,下面的代码有效,但由于某种原因,任何超过该尺寸的内容都会导致程序冻结并出现错误: “基础连接已关闭:接收时发生意外错误”

我做错了吗?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Net;

namespace FTP3
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void uploadFile(string filePath)
    {
        FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create("ftp://175.137.158.136" + "/" + Path.GetFileName(filePath));

        request.Method = WebRequestMethods.Ftp.UploadFile;
        request.Credentials = new NetworkCredential(username, password);
        request.UsePassive = true;
        request.UseBinary = true;
        request.KeepAlive = false;

        FileStream stream = File.OpenRead(filePath);
        byte[] buffer = new byte[stream.Length];

        stream.Read(buffer, 0, buffer.Length);
        stream.Close();

        Stream reqStream = request.GetRequestStream();
        reqStream.Write(buffer, 0, buffer.Length);
        reqStream.Close();

        MessageBox.Show("Upload complete!");

    }
    private void button1_Click(object sender, EventArgs e)
    {
        uploadFile(@"C:\Users\User\Desktop\test\data.xlsx");
    }
  }
}

1 个答案:

答案 0 :(得分:1)

您应该以“块”的形式上传文件,而不是完全上传。所以请尝试以下方法:

using (FileStream fileStream = File.OpenRead(filePath))
        {
            using (Stream reqStream = request.GetRequestStream())
            {
                long curFileStreamPos = 0;
                long chunkSize = 512;

                while (curFileStreamPos < fileStream.Length)
                {
                    if (fileStream.Length - curFileStreamPos < chunkSize)
                        chunkSize = fileStream.Length - curFileStreamPos;

                    byte[] buff = new byte[chunkSize];
                    fileStream.Read(buff, 0, buff.Length);
                    reqStream.Write(buff, 0, buff.Length);

                    curFileStreamPos += chunkSize;
                }

                reqStream.Close();
            }
            fileStream.Close();
        }

我没有测试过此代码段,所以请特别验证索引。 如果您一次上传文件,可能会因为准备要上传的数据而导致tcp / ip堆栈出现超时。

此外,这样您上传具有数百mb的文件时就不会创建大内存对象(这会在您的解决方案中完全在内存中)