อัปโหลดไฟล์ไปยัง FTP โดยใช้ C #


112

ฉันลองอัปโหลดไฟล์ไปยัง FTP-server ด้วย C # ไฟล์ถูกอัปโหลด แต่มีศูนย์ไบต์

private void button2_Click(object sender, EventArgs e)
{
    var dirPath = @"C:/Documents and Settings/sander.GD/Bureaublad/test/";

    ftp ftpClient = new ftp("ftp://example.com/", "username", "password");

    string[] files = Directory.GetFiles(dirPath,"*.*");

    var uploadPath = "/httpdocs/album";

    foreach (string file in files)
    {
        ftpClient.createDirectory("/test");

        ftpClient.upload(uploadPath + "/" + Path.GetFileName(file), file);
    }

    if (string.IsNullOrEmpty(txtnaam.Text))
    {
        MessageBox.Show("Gelieve uw naam in te geven !");
    }
}

18
ทำไมเกือบ 2 ปีต่อมาข้อมูลรับรอง FTP ดั้งเดิมยังคงใช้งานได้
FreeAsInBeer


คุณช่วยลองสิ่งที่กล่าวถึงในคำถามที่ @Frederic เชื่อมโยงและกลับมาได้ไหม ... เพิ่มเติมแม้ว่าจะไม่ชัดเจนว่าคุณใช้ api ใดสำหรับการอัปโหลด ftp ...
deostroll

คำตอบ:


273

คำตอบที่มีอยู่นั้นถูกต้อง แต่ทำไมต้องประดิษฐ์วงล้อขึ้นมาใหม่และต้องกังวลกับWebRequestประเภทระดับที่ต่ำกว่าในขณะที่WebClientดำเนินการอัปโหลด FTP เรียบร้อยแล้ว:

using (var client = new WebClient())
{
    client.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
    client.UploadFile("ftp://host/path.zip", WebRequestMethods.Ftp.UploadFile, localFile);
}

39
เพียงหนึ่งเซ็นต์: คุณสามารถแทนที่สตริงมายากล "STOR" สำหรับ WebRequestMethods.Ftp.UploadFile
คลิกตกลง

น่าเสียดายที่ดูเหมือนจะไม่มีวิธีใช้ WebClient เพื่อสร้างไดเร็กทอรีใหม่เพื่ออัปโหลดไฟล์
danludwig

1
PSA: ไม่แนะนำให้ใช้ webrequest อีกต่อไปตอนนี้เป็นทางเลือกอย่างเป็นทางการ
Pacharrin

สวัสดี path.zip ในเมธอด UploadFile บ่งบอกอะไร ฉันต้องใส่ชื่อไฟล์ไว้หลังชื่อโฮสต์หรือไม่? ฉันมีไฟล์ txt ที่จะส่งฉันคิดว่าชื่อไฟล์และพา ธ ไปยังไฟล์นั้นถูกกล่าวถึงใน localFile
Skanda

43
public void UploadFtpFile(string folderName, string fileName)
{

    FtpWebRequest request;

    string folderName; 
    string fileName;
    string absoluteFileName = Path.GetFileName(fileName);

    request = WebRequest.Create(new Uri(string.Format(@"ftp://{0}/{1}/{2}", "127.0.0.1", folderName, absoluteFileName))) as FtpWebRequest;
    request.Method = WebRequestMethods.Ftp.UploadFile;
    request.UseBinary = 1;
    request.UsePassive = 1;
    request.KeepAlive = 1;
    request.Credentials =  new NetworkCredential(user, pass);
    request.ConnectionGroupName = "group"; 

    using (FileStream fs = File.OpenRead(fileName))
    {
        byte[] buffer = new byte[fs.Length];
        fs.Read(buffer, 0, buffer.Length);
        fs.Close();
        Stream requestStream = request.GetRequestStream();
        requestStream.Write(buffer, 0, buffer.Length);
        requestStream.Flush();
        requestStream.Close();
    }
}

วิธีใช้

UploadFtpFile("testFolder", "E:\\filesToUpload\\test.img");

ใช้สิ่งนี้ใน foreach ของคุณ

และคุณต้องสร้างโฟลเดอร์เพียงครั้งเดียว

เพื่อสร้างโฟลเดอร์

request = WebRequest.Create(new Uri(string.Format(@"ftp://{0}/{1}/", "127.0.0.1", "testFolder"))) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.MakeDirectory;
FtpWebResponse ftpResponse = (FtpWebResponse)request.GetResponse();

3
request.GetResponse()คำตอบบอลเฉียงเรียกไปยัง หากไม่มีการอัปโหลดจะไม่ทำงาน (โดยถูกต้อง) บนเซิร์ฟเวอร์บางเครื่อง ดูวิธีการ: อัปโหลดไฟล์ที่มี FTP
Martin Prikryl

ฉันถูกล่อลวงให้ -1 เพื่อกลืนข้อยกเว้นอย่างเงียบ ๆ คุณช่วยลบ try-catch-block ที่เป็นอันตรายออกได้ไหม
Heinzi

33

วิธีที่ง่ายที่สุด

วิธีที่ง่ายที่สุดในการอัปโหลดไฟล์ไปยังเซิร์ฟเวอร์ FTP โดยใช้. NET framework คือใช้WebClient.UploadFileวิธีการ :

WebClient client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
client.UploadFile("ftp://ftp.example.com/remote/path/file.zip", @"C:\local\path\file.zip");

ตัวเลือกขั้นสูง

หากคุณจำเป็นต้องมีการควบคุมมากขึ้นที่WebClientไม่ได้นำเสนอ (เช่นTLS / การเข้ารหัส SSLโหมด ASCII โหมดการใช้งาน ฯลฯ ), FtpWebRequestการใช้งาน วิธีง่ายๆเพียงแค่คัดลอกFileStreamไปยังสตรีม FTP โดยใช้Stream.CopyTo:

FtpWebRequest request =
    (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.UploadFile;  

using (Stream fileStream = File.OpenRead(@"C:\local\path\file.zip"))
using (Stream ftpStream = request.GetRequestStream())
{
    fileStream.CopyTo(ftpStream);
}

การตรวจสอบความคืบหน้า

หากคุณต้องการตรวจสอบความคืบหน้าในการอัปโหลดคุณต้องคัดลอกเนื้อหาด้วยตัวเอง:

FtpWebRequest request =
    (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.UploadFile;  

using (Stream fileStream = File.OpenRead(@"C:\local\path\file.zip"))
using (Stream ftpStream = request.GetRequestStream())
{
    byte[] buffer = new byte[10240];
    int read;
    while ((read = fileStream.Read(buffer, 0, buffer.Length)) > 0)
    {
        ftpStream.Write(buffer, 0, read);
        Console.WriteLine("Uploaded {0} bytes", fileStream.Position);
    } 
}

สำหรับความคืบหน้า GUI (WinForms ProgressBar) โปรดดูตัวอย่าง C # ที่:
เราจะแสดงแถบความคืบหน้าสำหรับการอัปโหลดด้วย FtpWebRequest ได้อย่างไร


กำลังอัปโหลดโฟลเดอร์

หากคุณต้องการอัปโหลดไฟล์ทั้งหมดจากโฟลเดอร์ดู
ไดเรกทอรีอัพโหลดไฟล์ไปยังเซิร์ฟเวอร์ FTP ใช้ WebClient

สำหรับการอัปโหลดแบบเรียกซ้ำโปรดดูที่การ
อัปโหลดแบบเรียกซ้ำไปยังเซิร์ฟเวอร์ FTP ใน C #


10

สิ่งต่อไปนี้ใช้ได้กับฉัน:

public virtual void Send(string fileName, byte[] file)
{
    ByteArrayToFile(fileName, file);

    var request = (FtpWebRequest) WebRequest.Create(new Uri(ServerUrl + fileName));

    request.Method = WebRequestMethods.Ftp.UploadFile;
    request.UsePassive = false;
    request.Credentials = new NetworkCredential(UserName, Password);
    request.ContentLength = file.Length;

    var requestStream = request.GetRequestStream();
    requestStream.Write(file, 0, file.Length);
    requestStream.Close();

    var response = (FtpWebResponse) request.GetResponse();

    if (response != null)
        response.Close();
}

คุณไม่สามารถอ่านส่งพารามิเตอร์ไฟล์ในโค้ดของคุณได้เนื่องจากเป็นเพียงชื่อไฟล์เท่านั้น

ใช้สิ่งต่อไปนี้:

byte[] bytes = File.ReadAllBytes(dir + file);

เพื่อรับไฟล์เพื่อให้คุณสามารถส่งต่อไปยังSendเมธอด


สวัสดีฉันมีโฟลเดอร์ที่มีไฟล์อยู่ .. ฉันจะอัปโหลดไปยังเซิร์ฟเวอร์ FTP ได้อย่างไร? รหัสนี้ฉันไม่ทราบว่ามันทำงานอย่างไร?
webvision

ใน foreach loop เรียกวิธีนี้ด้วยอินพุตที่เหมาะสม
nRk

8
public static void UploadFileToFtp(string url, string filePath, string username, string password)
{
    var fileName = Path.GetFileName(filePath);
    var request = (FtpWebRequest)WebRequest.Create(url + fileName);

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

    using (var fileStream = File.OpenRead(filePath))
    {
        using (var requestStream = request.GetRequestStream())
        {
            fileStream.CopyTo(requestStream);
            requestStream.Close();
        }
    }

    var response = (FtpWebResponse)request.GetResponse();
    Console.WriteLine("Upload done: {0}", response.StatusDescription);
    response.Close();
}

ทำไมคุณถึงตั้ง KeepAlive = false คุณแน่ใจหรือไม่ว่าจำเป็นต้อง requestStream.Close ()? คุณใช้ requestStream ภายในโดยใช้ดังนั้นฉันคิดว่ามันจะปิดสตรีมด้วยตัวมันเอง
Kate

2

ในตัวอย่างแรกต้องเปลี่ยนสิ่งเหล่านี้เป็น:

requestStream.Flush();
requestStream.Close();

ล้างครั้งแรกและหลังจากนั้นปิด


1

วิธีนี้ใช้ได้ผลสำหรับฉันวิธีนี้จะส่งไฟล์ไปยังตำแหน่งภายในเครือข่ายของคุณ ใช้ห้องสมุด SSH.NET.2013.4.7 หนึ่งสามารถดาวน์โหลดได้ฟรี

    //Secure FTP
    public void SecureFTPUploadFile(string destinationHost,int port,string username,string password,string source,string destination)

    {
        ConnectionInfo ConnNfo = new ConnectionInfo(destinationHost, port, username, new PasswordAuthenticationMethod(username, password));

        var temp = destination.Split('/');
        string destinationFileName = temp[temp.Count() - 1];
        string parentDirectory = destination.Remove(destination.Length - (destinationFileName.Length + 1), destinationFileName.Length + 1);


        using (var sshclient = new SshClient(ConnNfo))
        {
            sshclient.Connect();
            using (var cmd = sshclient.CreateCommand("mkdir -p " + parentDirectory + " && chmod +rw " + parentDirectory))
            {
                cmd.Execute();
            }
            sshclient.Disconnect();
        }


        using (var sftp = new SftpClient(ConnNfo))
        {
            sftp.Connect();
            sftp.ChangeDirectory(parentDirectory);
            using (var uplfileStream = System.IO.File.OpenRead(source))
            {
                sftp.UploadFile(uplfileStream, destinationFileName, true);
            }
            sftp.Disconnect();
        }
    }

คำตอบนี้ดูเหมือนจะเป็นทางออกเดียวสำหรับ sftp ของฉัน รอทดสอบได้เลย
Olorunfemi Ajibulu

1

วันที่เผยแพร่: 26/26/2018

https://docs.microsoft.com/en-us/dotnet/framework/network-programming/how-to-upload-files-with-ftp

using System;
using System.IO;
using System.Net;
using System.Text;

namespace Examples.System.Net
{
    public class WebRequestGetExample
    {
    public static void Main ()
    {
        // Get the object used to communicate with the server.
        FtpWebRequest request = 
(FtpWebRequest)WebRequest.Create("ftp://www.contoso.com/test.htm");
        request.Method = WebRequestMethods.Ftp.UploadFile;

        // This example assumes the FTP site uses anonymous logon.
        request.Credentials = new NetworkCredential("anonymous", 
"janeDoe@contoso.com");

        // Copy the contents of the file to the request stream.
        byte[] fileContents;
        using (StreamReader sourceStream = new StreamReader("testfile.txt"))
        {
            fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
        }

        request.ContentLength = fileContents.Length;

        using (Stream requestStream = request.GetRequestStream())
        {
            requestStream.Write(fileContents, 0, fileContents.Length);
        }

        using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
        {
            Console.WriteLine($"Upload File Complete, status 
{response.StatusDescription}");
        }
    }
}
}

0

ฉันสังเกตว่า -

  1. FtpwebRequest หายไป
  2. เนื่องจากเป้าหมายคือ FTP ดังนั้นจึงจำเป็นต้องใช้ NetworkCredential

ฉันได้เตรียมวิธีการที่ใช้งานได้เช่นนี้คุณสามารถแทนที่ค่าของตัวแปร ftpurl ด้วยพารามิเตอร์ TargetDestinationPath ฉันได้ทดสอบวิธีนี้กับแอปพลิเคชัน winforms:

private void UploadProfileImage(string TargetFileName, string TargetDestinationPath, string FiletoUpload)
        {
            //Get the Image Destination path
            string imageName = TargetFileName; //you can comment this
            string imgPath = TargetDestinationPath; 

            string ftpurl = "ftp://downloads.abc.com/downloads.abc.com/MobileApps/SystemImages/ProfileImages/" + imgPath;
            string ftpusername = krayknot_DAL.clsGlobal.FTPUsername;
            string ftppassword = krayknot_DAL.clsGlobal.FTPPassword;
            string fileurl = FiletoUpload;

            FtpWebRequest ftpClient = (FtpWebRequest)FtpWebRequest.Create(ftpurl);
            ftpClient.Credentials = new System.Net.NetworkCredential(ftpusername, ftppassword);
            ftpClient.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
            ftpClient.UseBinary = true;
            ftpClient.KeepAlive = true;
            System.IO.FileInfo fi = new System.IO.FileInfo(fileurl);
            ftpClient.ContentLength = fi.Length;
            byte[] buffer = new byte[4097];
            int bytes = 0;
            int total_bytes = (int)fi.Length;
            System.IO.FileStream fs = fi.OpenRead();
            System.IO.Stream rs = ftpClient.GetRequestStream();
            while (total_bytes > 0)
            {
                bytes = fs.Read(buffer, 0, buffer.Length);
                rs.Write(buffer, 0, bytes);
                total_bytes = total_bytes - bytes;
            }
            //fs.Flush();
            fs.Close();
            rs.Close();
            FtpWebResponse uploadResponse = (FtpWebResponse)ftpClient.GetResponse();
            string value = uploadResponse.StatusDescription;
            uploadResponse.Close();
        }

แจ้งให้เราทราบในกรณีที่มีปัญหาใด ๆ หรือนี่คืออีกหนึ่งลิงก์ที่สามารถช่วยคุณได้:

https://msdn.microsoft.com/en-us/library/ms229715(v=vs.110).aspx

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.