csharp FTP代码c#
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp FTP代码c#相关的知识,希望对你有一定的参考价值。
/* Copyright (c) 2006, J.P. Trosclair
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this list of conditions and
* the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
* and the following disclaimer in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Based on FTPFactory.cs code, pretty much a complete re-write with FTPFactory.cs
* as a reference.
*
***********************
* Authors of this code:
***********************
* J.P. Trosclair (jptrosclair@judelawfirm.com)
* Filipe Madureira (filipe_madureira@hotmail.com)
* Carlo M. Andreoli (cmandreoli@numericaprogetti.it)
* Sloan Holliday (sloan@ipass.net)
*
***********************
* FTPFactory.cs was written by Jaimon Mathew (jaimonmathew@rediffmail.com)
* and modified by Dan Rolander (Dan.Rolander@marriott.com).
* http://www.csharphelp.com/archives/archive9.html
***********************
*
* ** DO NOT ** contact the authors of FTPFactory.cs about problems with this code. It
* is not their responsibility. Only contact people listed as authors of THIS CODE.
*
* Any bug fixes or additions to the code will be properly credited to the author.
*
* BUGS: There probably are plenty. If you fix one, please email me with info
* about the bug and the fix, code is welcome.
*
* All calls to the ftplib functions should be:
*
* try
* {
* // ftplib function call
* }
* catch(Exception ex)
* {
* // error handeler
* }
*
* If you add to the code please make use of OpenDataSocket(), CloseDataSocket(), and
* ReadResponse() appropriately. See the comments above each for info about using them.
*
* The Fail() function terminates the entire connection. Only call it on critical errors.
* Non critical errors should NOT close the connection.
* All errors should throw an exception of type Exception with the response string from
* the server as the message.
*
* See the simple ftp client for examples on using this class
*/
//#define FTP_DEBUG
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
namespace FTPLib
{
public class FTP
{
#region Public Variables
/// <summary>
/// IP address or hostname to connect to
/// </summary>
public string server;
/// <summary>
/// Username to login as
/// </summary>
public string user;
/// <summary>
/// Password for account
/// </summary>
public string pass;
/// <summary>
/// Port number the FTP server is listening on
/// </summary>
public int port;
/// <summary>
/// The timeout (miliseconds) for waiting on data to arrive
/// </summary>
public int timeout;
#endregion
#region Private Variables
private string messages; // server messages
private string responseStr; // server response if the user wants it.
private bool passive_mode; // #######################################
private long bytes_total; // upload/download info if the user wants it.
private long file_size; // gets set when an upload or download takes place
private Socket main_sock;
private IPEndPoint main_ipEndPoint;
private Socket listening_sock;
private Socket data_sock;
private IPEndPoint data_ipEndPoint;
private FileStream file;
private int response;
private string bucket;
#endregion
#region Constructors
/// <summary>
/// Constructor
/// </summary>
public FTP()
{
server = null;
user = null;
pass = null;
port = 21;
passive_mode = true; // #######################################
main_sock = null;
main_ipEndPoint = null;
listening_sock = null;
data_sock = null;
data_ipEndPoint = null;
file = null;
bucket = "";
bytes_total = 0;
timeout = 10000; // 10 seconds
messages = "";
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="server">Server to connect to</param>
/// <param name="user">Account to login as</param>
/// <param name="pass">Account password</param>
public FTP(string server, string user, string pass)
{
this.server = server;
this.user = user;
this.pass = pass;
port = 21;
passive_mode = true; // #######################################
main_sock = null;
main_ipEndPoint = null;
listening_sock = null;
data_sock = null;
data_ipEndPoint = null;
file = null;
bucket = "";
bytes_total = 0;
timeout = 10000; // 10 seconds
messages = "";
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="server">Server to connect to</param>
/// <param name="port">Port server is listening on</param>
/// <param name="user">Account to login as</param>
/// <param name="pass">Account password</param>
public FTP(string server, int port, string user, string pass)
{
this.server = server;
this.user = user;
this.pass = pass;
this.port = port;
passive_mode = true; // #######################################
main_sock = null;
main_ipEndPoint = null;
listening_sock = null;
data_sock = null;
data_ipEndPoint = null;
file = null;
bucket = "";
bytes_total = 0;
timeout = 10000; // 10 seconds
messages = "";
}
#endregion
/// <summary>
/// Connection status to the server
/// </summary>
public bool IsConnected
{
get
{
if (main_sock != null)
return main_sock.Connected;
return false;
}
}
/// <summary>
/// Returns true if the message buffer has data in it
/// </summary>
public bool MessagesAvailable
{
get
{
if (messages.Length > 0)
return true;
return false;
}
}
/// <summary>
/// Server messages if any, buffer is cleared after you access this property
/// </summary>
public string Messages
{
get
{
string tmp = messages;
messages = "";
return tmp;
}
}
/// <summary>
/// The response string from the last issued command
/// </summary>
public string ResponseString
{
get
{
return responseStr;
}
}
/// <summary>
/// The total number of bytes sent/recieved in a transfer
/// </summary>
public long BytesTotal // #######################################
{
get
{
return bytes_total;
}
}
/// <summary>
/// The size of the file being downloaded/uploaded (Can possibly be 0 if no size is available)
/// </summary>
public long FileSize // #######################################
{
get
{
return file_size;
}
}
/// <summary>
/// True: Passive mode [default]
/// False: Active Mode
/// </summary>
public bool PassiveMode // #######################################
{
get
{
return passive_mode;
}
set
{
passive_mode = value;
}
}
private void Fail()
{
Disconnect();
throw new Exception(responseStr);
}
private void SetBinaryMode(bool mode)
{
if (mode)
SendCommand("TYPE I");
else
SendCommand("TYPE A");
ReadResponse();
if (response != 200)
Fail();
}
private void SendCommand(string command)
{
Byte[] cmd = Encoding.ASCII.GetBytes((command + "\r\n").ToCharArray());
#if (FTP_DEBUG)
if (command.Length > 3 && command.Substring(0, 4) == "PASS")
Console.WriteLine("\rPASS xxx");
else
Console.WriteLine("\r" + command);
#endif
main_sock.Send(cmd, cmd.Length, 0);
}
private void FillBucket()
{
Byte[] bytes = new Byte[512];
long bytesgot;
int msecs_passed = 0; // #######################################
while (main_sock.Available < 1)
{
System.Threading.Thread.Sleep(50);
msecs_passed += 50;
// this code is just a fail safe option
// so the code doesn't hang if there is
// no data comming.
if (msecs_passed > timeout)
{
Disconnect();
throw new Exception("Timed out waiting on server to respond.");
}
}
while (main_sock.Available > 0)
{
bytesgot = main_sock.Receive(bytes, 512, 0);
bucket += Encoding.ASCII.GetString(bytes, 0, (int)bytesgot);
// this may not be needed, gives any more data that hasn't arrived
// just yet a small chance to get there.
System.Threading.Thread.Sleep(50);
}
}
private string GetLineFromBucket()
{
int i;
string buf = "";
if ((i = bucket.IndexOf('\n')) < 0)
{
while (i < 0)
{
FillBucket();
i = bucket.IndexOf('\n');
}
}
buf = bucket.Substring(0, i);
bucket = bucket.Substring(i + 1);
return buf;
}
// Any time a command is sent, use ReadResponse() to get the response
// from the server. The variable responseStr holds the entire string and
// the variable response holds the response number.
private void ReadResponse()
{
string buf;
messages = "";
while (true)
{
//buf = GetLineFromBucket();
buf = GetLineFromBucket();
#if (FTP_DEBUG)
Console.WriteLine(buf);
#endif
// the server will respond with "000-Foo bar" on multi line responses
// "000 Foo bar" would be the last line it sent for that response.
// Better example:
// "000-This is a multiline response"
// "000-Foo bar"
// "000 This is the end of the response"
if (Regex.Match(buf, "^[0-9]+ ").Success)
{
responseStr = buf;
response = int.Parse(buf.Substring(0, 3));
break;
}
else
messages += Regex.Replace(buf, "^[0-9]+-", "") + "\n";
}
}
// if you add code that needs a data socket, i.e. a PASV or PORT command required,
// call this function to do the dirty work. It sends the PASV or PORT command,
// parses out the port and ip info and opens the appropriate data socket
// for you. The socket variable is private Socket data_socket. Once you
// are done with it, be sure to call CloseDataSocket()
private void OpenDataSocket()
{
if (passive_mode) // #######################################
{
string[] pasv;
string server;
int port;
Connect();
SendCommand("PASV");
ReadResponse();
if (response != 227)
Fail();
try
{
int i1, i2;
i1 = responseStr.IndexOf('(') + 1;
i2 = responseStr.IndexOf(')') - i1;
pasv = responseStr.Substring(i1, i2).Split(',');
}
catch (Exception)
{
Disconnect();
throw new Exception("Malformed PASV response: " + responseStr);
}
if (pasv.Length < 6)
{
Disconnect();
throw new Exception("Malformed PASV response: " + responseStr);
}
server = String.Format("{0}.{1}.{2}.{3}", pasv[0], pasv[1], pasv[2], pasv[3]);
port = (int.Parse(pasv[4]) << 8) + int.Parse(pasv[5]);
try
{
#if (FTP_DEBUG)
Console.WriteLine("Data socket: {0}:{1}", server, port);
#endif
CloseDataSocket();
#if (FTP_DEBUG)
Console.WriteLine("Creating socket...");
#endif
data_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
#if (FTP_DEBUG)
Console.WriteLine("Resolving host");
#endif
data_ipEndPoint = new IPEndPoint(Dns.GetHostEntry(server).AddressList[0], port);
#if (FTP_DEBUG)
Console.WriteLine("Connecting..");
#endif
data_sock.Connect(data_ipEndPoint);
#if (FTP_DEBUG)
Console.WriteLine("Connected.");
#endif
}
catch (Exception ex)
{
throw new Exception("Failed to connect for data transfer: " + ex.Message);
}
}
else // #######################################
{
Connect();
try
{
#if (FTP_DEBUG)
Console.WriteLine("Data socket (active mode)");
#endif
CloseDataSocket();
#if (FTP_DEBUG)
Console.WriteLine("Creating listening socket...");
#endif
listening_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
#if (FTP_DEBUG)
Console.WriteLine("Binding it to local address/port");
#endif
// for the PORT command we need to send our IP address; let's extract it
// from the LocalEndPoint of the main socket, that's already connected
string sLocAddr = main_sock.LocalEndPoint.ToString();
int ix = sLocAddr.IndexOf(':');
if (ix < 0)
{
throw new Exception("Failed to parse the local address: " + sLocAddr);
}
string sIPAddr = sLocAddr.Substring(0, ix);
// let the system automatically assign a port number (setting port = 0)
System.Net.IPEndPoint localEP = new IPEndPoint(IPAddress.Parse(sIPAddr), 0);
listening_sock.Bind(localEP);
sLocAddr = listening_sock.LocalEndPoint.ToString();
ix = sLocAddr.IndexOf(':');
if (ix < 0)
{
throw new Exception("Failed to parse the local address: " + sLocAddr);
}
int nPort = int.Parse(sLocAddr.Substring(ix + 1));
#if (FTP_DEBUG)
Console.WriteLine("Listening on {0}:{1}", sIPAddr, nPort);
#endif
// start to listen for a connection request from the host (note that
// Listen is not blocking) and send the PORT command
listening_sock.Listen(1);
string sPortCmd = string.Format("PORT {0},{1},{2}",
sIPAddr.Replace('.', ','),
nPort / 256, nPort % 256);
SendCommand(sPortCmd);
ReadResponse();
if (response != 200)
Fail();
}
catch (Exception ex)
{
throw new Exception("Failed to connect for data transfer: " + ex.Message);
}
}
}
private void ConnectDataSocket() // #######################################
{
if (data_sock != null) // already connected (always so if passive mode)
return;
try
{
#if (FTP_DEBUG)
Console.WriteLine("Accepting the data connection.");
#endif
data_sock = listening_sock.Accept(); // Accept is blocking
listening_sock.Close();
listening_sock = null;
if (data_sock == null)
{
throw new Exception("Winsock error: " +
Convert.ToString(System.Runtime.InteropServices.Marshal.GetLastWin32Error()));
}
#if (FTP_DEBUG)
Console.WriteLine("Connected.");
#endif
}
catch (Exception ex)
{
throw new Exception("Failed to connect for data transfer: " + ex.Message);
}
}
private void CloseDataSocket()
{
#if (FTP_DEBUG)
Console.WriteLine("Attempting to close data channel socket...");
#endif
if (data_sock != null)
{
if (data_sock.Connected)
{
#if (FTP_DEBUG)
Console.WriteLine("Closing data channel socket!");
#endif
data_sock.Close();
#if (FTP_DEBUG)
Console.WriteLine("Data channel socket closed!");
#endif
}
data_sock = null;
}
data_ipEndPoint = null;
}
/// <summary>
/// Closes all connections to the ftp server
/// </summary>
public void Disconnect()
{
CloseDataSocket();
if (main_sock != null)
{
if (main_sock.Connected)
{
SendCommand("QUIT");
main_sock.Close();
}
main_sock = null;
}
if (file != null)
file.Close();
main_ipEndPoint = null;
file = null;
}
/// <summary>
/// Connect to a ftp server
/// </summary>
/// <param name="server">IP or hostname of the server to connect to</param>
/// <param name="port">Port number the server is listening on</param>
/// <param name="user">Account name to login as</param>
/// <param name="pass">Password for the account specified</param>
public void Connect(string server, int port, string user, string pass)
{
this.server = server;
this.user = user;
this.pass = pass;
this.port = port;
Connect();
}
/// <summary>
/// Connect to a ftp server
/// </summary>
/// <param name="server">IP or hostname of the server to connect to</param>
/// <param name="user">Account name to login as</param>
/// <param name="pass">Password for the account specified</param>
public void Connect(string server, string user, string pass)
{
this.server = server;
this.user = user;
this.pass = pass;
Connect();
}
/// <summary>
/// Connect to an ftp server
/// </summary>
public void Connect()
{
if (server == null)
throw new Exception("No server has been set.");
if (user == null)
throw new Exception("No username has been set.");
if (main_sock != null)
if (main_sock.Connected)
return;
main_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
main_ipEndPoint = new IPEndPoint(Dns.GetHostEntry(server).AddressList[0], port);
try
{
main_sock.Connect(main_ipEndPoint);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
ReadResponse();
if (response != 220)
Fail();
SendCommand("USER " + user);
ReadResponse();
switch (response)
{
case 331:
if (pass == null)
{
Disconnect();
throw new Exception("No password has been set.");
}
SendCommand("PASS " + pass);
ReadResponse();
if (response != 230)
Fail();
break;
case 230:
break;
}
return;
}
/// <summary>
/// Retrieves a list of files from the ftp server
/// </summary>
/// <returns>An ArrayList of files</returns>
public ArrayList List()
{
Byte[] bytes = new Byte[512];
string file_list = "";
long bytesgot = 0;
int msecs_passed = 0;
ArrayList list = new ArrayList();
Connect();
OpenDataSocket();
SendCommand("LIST");
ReadResponse();
//FILIPE MADUREIRA.
//Added response 125
switch (response)
{
case 125:
case 150:
break;
default:
CloseDataSocket();
throw new Exception(responseStr);
}
ConnectDataSocket(); // #######################################
while (data_sock.Available < 1)
{
System.Threading.Thread.Sleep(50);
msecs_passed += 50;
// this code is just a fail safe option
// so the code doesn't hang if there is
// no data comming.
if (msecs_passed > (timeout / 10))
{
//CloseDataSocket();
//throw new Exception("Timed out waiting on server to respond.");
//FILIPE MADUREIRA.
//If there are no files to list it gives timeout.
//So I wait less time and if no data is received, means that there are no files
break;//Maybe there are no files
}
}
while (data_sock.Available > 0)
{
bytesgot = data_sock.Receive(bytes, bytes.Length, 0);
file_list += Encoding.ASCII.GetString(bytes, 0, (int)bytesgot);
System.Threading.Thread.Sleep(50); // *shrug*, sometimes there is data comming but it isn't there yet.
}
CloseDataSocket();
ReadResponse();
if (response != 226)
throw new Exception(responseStr);
foreach (string f in file_list.Split('\n'))
{
if (f.Length > 0 && !Regex.Match(f, "^total").Success)
list.Add(f.Substring(0, f.Length - 1));
}
return list;
}
/// <summary>
/// Gets a file list only
/// </summary>
/// <returns>ArrayList of files only</returns>
public ArrayList ListFiles()
{
ArrayList list = new ArrayList();
foreach (string f in List())
{
//FILIPE MADUREIRA
//In Windows servers it is identified by <DIR>
if ((f.Length > 0))
{
if ((f[0] != 'd') && (f.ToUpper().IndexOf("<DIR>") < 0))
list.Add(f);
}
}
return list;
}
/// <summary>
/// Gets a directory list only
/// </summary>
/// <returns>ArrayList of directories only</returns>
public ArrayList ListDirectories()
{
ArrayList list = new ArrayList();
foreach (string f in List())
{
//FILIPE MADUREIRA
//In Windows servers it is identified by <DIR>
if (f.Length > 0)
{
if ((f[0] == 'd') || (f.ToUpper().IndexOf("<DIR>") >= 0))
list.Add(f);
}
}
return list;
}
/// <summary>
/// Returns the 'Raw' DateInformation in ftp format. (YYYYMMDDhhmmss). Use GetFileDate to return a DateTime object as a better option.
/// </summary>
/// <param name="fileName">Remote FileName to Query</param>
/// <returns>Returns the 'Raw' DateInformation in ftp format</returns>
public string GetFileDateRaw(string fileName)
{
Connect();
SendCommand("MDTM " + fileName);
ReadResponse();
if (response != 213)
{
#if (FTP_DEBUG)
Console.Write("\r" + responseStr);
#endif
throw new Exception(responseStr);
}
return (this.responseStr.Substring(4));
}
/// <summary>
/// GetFileDate will query the ftp server for the date of the remote file.
/// </summary>
/// <param name="fileName">Remote FileName to Query</param>
/// <returns>DateTime of the Input FileName</returns>
public DateTime GetFileDate(string fileName)
{
return ConvertFTPDateToDateTime(GetFileDateRaw(fileName));
}
private DateTime ConvertFTPDateToDateTime(string input)
{
if (input.Length < 14)
throw new ArgumentException("Input Value for ConvertFTPDateToDateTime method was too short.");
//YYYYMMDDhhmmss":
int year = Convert.ToInt16(input.Substring(0, 4));
int month = Convert.ToInt16(input.Substring(4, 2));
int day = Convert.ToInt16(input.Substring(6, 2));
int hour = Convert.ToInt16(input.Substring(8, 2));
int min = Convert.ToInt16(input.Substring(10, 2));
int sec = Convert.ToInt16(input.Substring(12, 2));
return new DateTime(year, month, day, hour, min, sec);
}
/// <summary>
/// Get the working directory on the ftp server
/// </summary>
/// <returns>The working directory</returns>
public string GetWorkingDirectory()
{
//PWD - print working directory
Connect();
SendCommand("PWD");
ReadResponse();
if (response != 257)
throw new Exception(responseStr);
string pwd;
try
{
pwd = responseStr.Substring(responseStr.IndexOf("\"", 0) + 1);//5);
pwd = pwd.Substring(0, pwd.LastIndexOf("\""));
pwd = pwd.Replace("\"\"", "\""); // directories with quotes in the name come out as "" from the server
}
catch (Exception ex)
{
throw new Exception("Uhandled PWD response: " + ex.Message);
}
return pwd;
}
/// <summary>
/// Change to another directory on the ftp server
/// </summary>
/// <param name="path">Directory to change to</param>
public void ChangeDir(string path)
{
Connect();
SendCommand("CWD " + path);
ReadResponse();
if (response != 250)
{
#if (FTP_DEBUG)
Console.Write("\r" + responseStr);
#endif
throw new Exception(responseStr);
}
}
/// <summary>
/// Create a directory on the ftp server
/// </summary>
/// <param name="dir">Directory to create</param>
public void MakeDir(string dir)
{
Connect();
SendCommand("MKD " + dir);
ReadResponse();
switch (response)
{
case 257:
case 250:
break;
default:
#if (FTP_DEBUG)
Console.Write("\r" + responseStr);
#endif
throw new Exception(responseStr);
}
}
/// <summary>
/// Remove a directory from the ftp server
/// </summary>
/// <param name="dir">Name of directory to remove</param>
public void RemoveDir(string dir)
{
Connect();
SendCommand("RMD " + dir);
ReadResponse();
if (response != 250)
{
#if (FTP_DEBUG)
Console.Write("\r" + responseStr);
#endif
throw new Exception(responseStr);
}
}
/// <summary>
/// Remove a file from the ftp server
/// </summary>
/// <param name="filename">Name of the file to delete</param>
public void RemoveFile(string filename)
{
Connect();
SendCommand("DELE " + filename);
ReadResponse();
if (response != 250)
{
#if (FTP_DEBUG)
Console.Write("\r" + responseStr);
#endif
throw new Exception(responseStr);
}
}
/// <summary>
/// Rename a file on the ftp server
/// </summary>
/// <param name="oldfilename">Old file name</param>
/// <param name="newfilename">New file name</param>
public void RenameFile(string oldfilename, string newfilename) // #######################################
{
Connect();
SendCommand("RNFR " + oldfilename);
ReadResponse();
if (response != 350)
{
#if (FTP_DEBUG)
Console.Write("\r" + responseStr);
#endif
throw new Exception(responseStr);
}
else
{
SendCommand("RNTO " + newfilename);
ReadResponse();
if (response != 250)
{
#if (FTP_DEBUG)
Console.Write("\r" + responseStr);
#endif
throw new Exception(responseStr);
}
}
}
/// <summary>
/// Get the size of a file (Provided the ftp server supports it)
/// </summary>
/// <param name="filename">Name of file</param>
/// <returns>The size of the file specified by filename</returns>
public long GetFileSize(string filename)
{
Connect();
SendCommand("TYPE I");
ReadResponse();
SendCommand("SIZE " + filename);
ReadResponse();
if (response != 213)
{
#if (FTP_DEBUG)
Console.Write("\r" + responseStr);
#endif
throw new Exception(responseStr);
}
return Int64.Parse(responseStr.Substring(4));
}
/// <summary>
/// Open an upload with no resume if it already exists
/// </summary>
/// <param name="filename">File to upload</param>
public void OpenUpload(string filename)
{
OpenUpload(filename, filename, false);
}
/// <summary>
/// Open an upload with no resume if it already exists
/// </summary>
/// <param name="filename">Local file to upload (Can include path to file)</param>
/// <param name="remotefilename">Filename to store file as on ftp server</param>
public void OpenUpload(string filename, string remotefilename)
{
OpenUpload(filename, remotefilename, false);
}
/// <summary>
/// Open an upload with resume support
/// </summary>
/// <param name="filename">Local file to upload (Can include path to file)</param>
/// <param name="resume">Attempt resume if exists</param>
public void OpenUpload(string filename, bool resume)
{
OpenUpload(filename, filename, resume);
}
/// <summary>
/// Open an upload with resume support
/// </summary>
/// <param name="filename">Local file to upload (Can include path to file)</param>
/// <param name="remote_filename">Filename to store file as on ftp server</param>
/// <param name="resume">Attempt resume if exists</param>
public void OpenUpload(string filename, string remote_filename, bool resume)
{
Connect();
SetBinaryMode(true);
OpenDataSocket();
bytes_total = 0;
try
{
file = new FileStream(filename, FileMode.Open);
}
catch (Exception ex)
{
file = null;
throw new Exception(ex.Message);
}
file_size = file.Length;
if (resume)
{
long size = GetFileSize(remote_filename);
SendCommand("REST " + size);
ReadResponse();
if (response == 350)
file.Seek(size, SeekOrigin.Begin);
}
SendCommand("STOR " + remote_filename);
ReadResponse();
switch (response)
{
case 125:
case 150:
break;
default:
file.Close();
file = null;
throw new Exception(responseStr);
}
ConnectDataSocket(); // #######################################
return;
}
/// <summary>
/// Download a file with no resume
/// </summary>
/// <param name="filename">Remote file name</param>
public void OpenDownload(string filename)
{
OpenDownload(filename, filename, false);
}
/// <summary>
/// Download a file with optional resume
/// </summary>
/// <param name="filename">Remote file name</param>
/// <param name="resume">Attempt resume if file exists</param>
public void OpenDownload(string filename, bool resume)
{
OpenDownload(filename, filename, resume);
}
/// <summary>
/// Download a file with no attempt to resume
/// </summary>
/// <param name="filename">Remote filename</param>
/// <param name="localfilename">Local filename (Can include path to file)</param>
public void OpenDownload(string filename, string localfilename)
{
OpenDownload(filename, localfilename, false);
}
/// <summary>
/// Open a file for download
/// </summary>
/// <param name="remote_filename">The name of the file on the FTP server</param>
/// <param name="local_filename">The name of the file to save as (Can include path to file)</param>
/// <param name="resume">Attempt resume if file exists</param>
public void OpenDownload(string remote_filename, string local_filename, bool resume)
{
Connect();
SetBinaryMode(true);
bytes_total = 0;
try
{
file_size = GetFileSize(remote_filename);
}
catch
{
file_size = 0;
}
if (resume && File.Exists(local_filename))
{
try
{
file = new FileStream(local_filename, FileMode.Open);
}
catch (Exception ex)
{
file = null;
throw new Exception(ex.Message);
}
SendCommand("REST " + file.Length);
ReadResponse();
if (response != 350)
throw new Exception(responseStr);
file.Seek(file.Length, SeekOrigin.Begin);
bytes_total = file.Length;
}
else
{
try
{
file = new FileStream(local_filename, FileMode.Create);
}
catch (Exception ex)
{
file = null;
throw new Exception(ex.Message);
}
}
OpenDataSocket();
SendCommand("RETR " + remote_filename);
ReadResponse();
switch (response)
{
case 125:
case 150:
break;
default:
file.Close();
file = null;
throw new Exception(responseStr);
}
ConnectDataSocket(); // #######################################
return;
}
/// <summary>
/// Upload the file, to be used in a loop until file is completely uploaded
/// </summary>
/// <returns>Bytes sent</returns>
public long DoUpload()
{
Byte[] bytes = new Byte[512];
long bytes_got;
try
{
bytes_got = file.Read(bytes, 0, bytes.Length);
bytes_total += bytes_got;
data_sock.Send(bytes, (int)bytes_got, 0);
if (bytes_got <= 0)
{
// the upload is complete or an error occured
file.Close();
file = null;
CloseDataSocket();
ReadResponse();
switch (response)
{
case 226:
case 250:
break;
default:
throw new Exception(responseStr);
}
SetBinaryMode(false);
}
}
catch (Exception ex)
{
file.Close();
file = null;
CloseDataSocket();
ReadResponse();
SetBinaryMode(false);
throw ex;
}
return bytes_got;
}
/// <summary>
/// Download a file, to be used in a loop until the file is completely downloaded
/// </summary>
/// <returns>Number of bytes recieved</returns>
public long DoDownload()
{
Byte[] bytes = new Byte[512];
long bytes_got;
try
{
bytes_got = data_sock.Receive(bytes, bytes.Length, 0);
if (bytes_got <= 0)
{
// the download is done or an error occured
CloseDataSocket();
file.Close();
file = null;
ReadResponse();
switch (response)
{
case 226:
case 250:
break;
default:
throw new Exception(responseStr);
}
SetBinaryMode(false);
return bytes_got;
}
file.Write(bytes, 0, (int)bytes_got);
bytes_total += bytes_got;
}
catch (Exception ex)
{
CloseDataSocket();
file.Close();
file = null;
ReadResponse();
SetBinaryMode(false);
throw ex;
}
return bytes_got;
}
}
}
以上是关于csharp FTP代码c#的主要内容,如果未能解决你的问题,请参考以下文章
csharp Enviar un fichero来自FTP usando C#para .NET