.NET FTP upload files

//帮助类 FTPHelper
namespace Common.FTP
{
	/// <summary>
	/// FTP的相关操作
	/// </summary>
	public class FTPHelper
	{
		//static readonly log4net.ILog log = log4net.LogManager.GetLogger("log4net");
		private string remoteHost, remotePath, remoteUser, remotePass, mes;
		private int remotePort, bytes;
		private Socket clientSocket;
		private int retValue;
		private Boolean debug;
		private Boolean logined;
		private string reply;

		private static int BLOCK_SIZE = 512;
		private Byte[] buffer = new Byte[BLOCK_SIZE];
        private Encoding ASCII = Encoding.ASCII;
        private Encoding Default = Encoding.Default;

		public FTPHelper()
		{
			remoteHost = "";
			remotePath = ".";
			remoteUser = "anonymous";
			remotePass = "";
			remotePort = 21;

			debug = false;
			logined = false;
		}


		public FTPHelper(string sRemoteHost,string sRemotePath,string sRemoteUser,string sRemotePassword,int iRemotePort)
		{
			remoteHost = sRemoteHost;
			remotePath = sRemotePath;
			remoteUser = sRemoteUser;
			remotePass = sRemotePassword;
			remotePort = iRemotePort;

			debug = false;
			logined = false;
		}

		///
		/// Set the name of the FTP server to connect to.
		///
		/// Server name
		public void setRemoteHost(string remoteHost)
		{
			this.remoteHost = remoteHost;
		}

		///
		/// Return the name of the current FTP server.
		///
		/// Server name
		public string getRemoteHost()
		{
			return remoteHost;
		}

		///
		/// Set the port number to use for FTP.
		///
		/// Port number
		public void setRemotePort(int remotePort)
		{
			this.remotePort = remotePort;
		}

		///
		/// Return the current port number.
		///
		/// Current port number
		public int getRemotePort()
		{
			return remotePort;
		}

		///
		/// Set the remote directory path.
		///
		/// The remote directory path
		public void setRemotePath(string remotePath)
		{
			this.remotePath = remotePath;
		}

		///
		/// Return the current remote directory path.
		///
		/// The current remote directory path.
		public string getRemotePath()
		{
			return remotePath;
		}

		///
		/// Set the user name to use for logging into the remote server.
		///
		/// Username
		public void setRemoteUser(string remoteUser)
		{
			= remoteUser this.remoteUser; 
		} 

		///
		/// The password to the Set for the logging INTO The Remote User Server. 
		/// 
		/// Password 
		public void setRemotePass (String remotePass) 
		{ 
			this.remotePass = remotePass; 
		} 

		/// 
		/// It returns a list of files from the file system. It returns the file in the string () function. . 
		/// 
		/// 
		/// 
		public String [] getFileList (String mask) 
		{ 
			IF (logined!) 
			{ 
				Login (); 
			} 

			the Socket createDataSocket CSocket = (); 

			sendCommand ( "the NLST" + mask); 

			IF (! (150 || retValue retValue == == 125)) 
			{ 
				the throw new new IOException (reply.Substring (. 4)); 
			} 

			MES = ""; 
			the Thread.Sleep (700); 

			the while (to true)
			{
				if (cSocket.Connected)
				{
					int bytes = cSocket.Receive(buffer, buffer.Length, 0);
					mes += Default.GetString(buffer, 0, bytes);
					if (bytes < buffer.Length)
					{
						break;
					}
				}
				else
				{
					//log.Info("socket 连接断了!");
				}

			}
			//log.Info(mes);
			char[] seperator = {'\n'};
			string[] mess = mes.Split(seperator);
			//foreach(string fileName in mess)
			//{
			//log.Info(fileName);
			//}

			cSocket.Close();
			readReply();

			if (retValue != 226)
			{
				throw new IOException(reply.Substring(4));
			}
			return mess;
		}

		public string[] getFileList()
		{
			if (!logined)
			{
				login();
			}

			Socket cSocket = createDataSocket();

			sendCommand("LIST ");

			if (!(retValue == 150 || retValue == 125))
			{
				throw new IOException(reply.Substring(4));
			}

			mes = "";

			while (true)
			{
				int bytes = cSocket.Receive(buffer, buffer.Length, 0);
				mes += Default.GetString(buffer, 0, bytes);

				if (bytes < buffer.Length)
				{
					break;
				}
			}

			//log.Info(mes);
			char[] seperator = {'\n'};
			string[] mess = mes.Split(seperator);
			cSocket.Close();

			readReply();

			if (retValue != 226)
			{
				throw new IOException(reply.Substring(4));
			}

			return mess;
		}

		///
		/// 得到FTP服务器上的文件大小.
		///
		///
		///
		public long getFileSize(string fileName)
		{
			if (!logined)
			{
				login();
			}

			sendCommand("SIZE " + fileName);

			long size = 0;

			if (retValue == 213)
			{
				size = Int64.Parse(reply.Substring(4));
			}
			else
			{
				throw new IOException(reply.Substring(4));
			}

			return size;
		}

		///
		/// 登录FTP服务器
		///
		public void login()
		{
			clientSocket = new     Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

			IPEndPoint ep = new   IPEndPoint(Dns.Resolve(remoteHost).AddressList[0], remotePort);

			try
			{
				clientSocket.Connect(ep);
			}
			catch (Exception)
			{
				throw new IOException("Couldn't connect to remote server");
			}

			readReply();

			if (retValue != 220)
			{
				close();
				throw new IOException(reply.Substring(4));
			}

			if (debug)
				Console.WriteLine("USER " + remoteUser);

			sendCommand("USER " + remoteUser);

			if (!(retValue == 331 || retValue == 230))
			{
				cleanup();
				throw new IOException(reply.Substring(4));
			}

			if (retValue != 230)
			{
				if (debug)
					Console.WriteLine("PASS xxx");

				sendCommand("PASS " + remotePass);

				if (!(retValue == 230 || retValue == 202))
				{
					cleanup();
					throw new IOException(reply.Substring(4));
				}
			}

			logined = true;
			Console.WriteLine ( "Connected to" + remoteHost); 

			the chdir (the remotePath); 
		/// the Download File to A local apos Assembly The Directory, 
		/// The Same keeping File name. 
		///
		}

		/// 
		/// If the pattern is true for download to binary mode. Otherwise, set to Default mode 
		/// Else, Ascii SET MODE. 
		/// 
		/// 
		public void setBinaryMode (Boolean MODE) 
		{ 
			IF (MODE) 
			{ 
				sendCommand ( "the I the TYPE"); 
			} 
			the else 
			{ 
				sendCommand ( "the TYPE A "); 
			} 
			IF (= 200 is retValue)! 
			{ 
				the throw new new IOException (reply.Substring (. 4)); 
			} 
		} 

		/// 
		/// configured to download a file to the local directory. To keep the same file name. 
		void downloads public (String remFileName) 
		{ 
			downloads (remFileName, "", to false); 
		} 

		/// 
		/// A Remote File to the Download apos local Assembly The Directory, 
		/// The Same keeping File name, and SET The Resume In Flag. 
		/// 
		/// 
		/// download a remote file to a local folder configured. To keep the same file name. 
		void downloads public (String remFileName, Boolean Resume) 
		{ 
			downloads (remFileName, "", Resume); 
		} 

		/// 
		/// the Download Remote File A to File A local name Which the include CAN 
		. /// A path name of The local File BE the Created or overwritten by Will, 
		/// But at The path the MUST exist. 
		///
		/// download a remote file on the local file name. You must include a path. 
		/// local file name will be created or will be rewritten, but the path must exist. 
		void downloads public (remFileName String, String locFileName) 
		{
			downloads (remFileName, locFileName, to false); 
		} 

		/// 
		/// A Remote File to the Download File name A local CAN Which the include 
		/// path A, and SET The local File name of The Resume In Flag Will BE. 
		/// Created overwritten or, at The path But the MUST exist. 
		/// 
		/// for a local file name to download a remote file. You must include a path. 
		/// set the recovery flag. Local file name will be created or rewritten, but the local path must exist. 
		/// 
		public void downloads (remFileName String, String locFileName, Boolean Resume) 
		{ 
			IF (logined!) 
			{ 
				Login (); 
			} 
			setBinaryMode (to false);
 
			Console.WriteLine ( "Downloading File" + remFileName + "from" + + remoteHost "//" + remotePath); 

			IF (locFileName.Equals ( "
			{
				locFileName = remFileName;
			}

			if (!System.IO.File.Exists(locFileName))
			{
				Stream st = System.IO.File.Create(locFileName);
				st.Close();
			}

			FileStream output = new FileStream(locFileName, FileMode.Create);
			Socket cSocket = createDataSocket();
			long offset = 0;

			if (resume)
			{
				offset = output.Length;
				if (offset > 0)
				{
					setBinaryMode(false);
					sendCommand("REST " + offset);
					if (retValue != 350)
					{
						//throw new IOException(reply.Substring(4));
						//Some servers may not support resuming.
						offset = 0;
					}
				}

				if (offset > 0)
				{
					if (debug)
					{
						Console.WriteLine("seeking to " + offset);
					}
					long npos = output.Seek(offset, SeekOrigin.Begin);
					Console.WriteLine("new pos=" + npos);
				}
			}

			sendCommand("RETR " + remFileName);

			if (!(retValue == 150 || retValue == 125))
			{
				throw new IOException(reply.Substring(4));
			}


			while (true)
			{
				= cSocket.Receive bytes (Buffer, buffer.Length, 0); 
				output.Write (Buffer, 0, bytes); 

				IF (bytes <= 0) 
				{ 
					BREAK; 
				} 
			} 

			output.Close (); 

			if (cSocket.Connected)
			{
				cSocket.Close (); 
			} 

			Console.WriteLine ( ""); 
			readReply (); 

			IF ((|| retValue retValue == == 226 250)!) 
			{ 
				the throw new new IOException (reply.Substring (. 4)); 
			} 
		} 

		/// 
		/// . the upload the System.IO.File a 
		/// 
		/// this is you from a local hard disk to your FTP file folder on the file upload function 
        public void upload (String fileName) 
		{ 
			upload (fileName, to false); 
		} 

		/// 
		. a /// the upload File and the sET at the resume flag 
		/// 
		/// 
		/// this is a sign to recover from your local hard drive to upload functions and settings on your FTP page 
		public Upload void (String fileName, Boolean Resume) 
		{ 
			IF (! logined) 
			{ 
				Login (); 
			} 
			the Socket CSocket = createDataSocket (); 
			Long offset = 0; 

			IF (Resume) 
			{ 
				the try 
				{ 
					setBinaryMode (to true); 
					offset = getFileSize (fileName); 
				} 
				the catch (Exception) 
				{ 
					offset = 0; 
				} 
			} 

			IF (offset> 0) 
			{ 
				sendCommand ( "the REST" + offset); 
				IF (! retValue = 350) 
				{
					//throw new IOException(reply.Substring(4));
					//Remote server may not support resuming.
					offset = 0;
				}
			}

			/*==========================*/
			sendCommand("STOR " + Path.GetFileName(fileName));
			if (!(retValue == 125 || retValue == 150))
			{
				throw new IOException(reply.Substring(4));
			}

			// open input stream to read source file
			FileStream input = new FileStream(fileName, FileMode.Open);

			if (offset != 0)
			{
				if (debug)
				{
					Console.WriteLine("seeking to " + offset);
				}
				input.Seek(offset, SeekOrigin.Begin);
			}

			Console.WriteLine("Uploading file " + fileName + " to " + remotePath);

			while ((bytes = input.Read(buffer, 0, buffer.Length)) > 0)
			{
				cSocket.Send(buffer, bytes, 0);
			}

			input.Close();
			Console.WriteLine("");

			if (cSocket.Connected)
			{
				cSocket.Close();
			}

			readReply();
			if (!(retValue == 226 || retValue == 250))
			{
				throw new IOException(reply.Substring(4));
			}
		}



		///
		/// Delete a file from the remote FTP server.
		///
		/// 从远程FTP服务器上删除一个文件。
		public void deleteRemoteFile(string fileName)
		{
			if (!logined)
			{
				login();
			}
			sendCommand("DELE " + fileName);

			if (retValue != 250)
			{
				throw new IOException(reply.Substring(4));
			}
		}

		///
		/// Rename a file on the remote FTP server.
		///
		///
		/// 在远程FTP服务器上重命名一个文件
		public void renameRemoteFile(string oldFileName, string newFileName)
		{
			if (!logined)
			{
				login();
			}
			sendCommand("RNFR " + oldFileName);

			if (retValue != 350)
			{
				throw new IOException(reply.Substring(4));
			}
			// known problem
			// rnto will not take care of existing System.IO.File.
			// i.e. It will overwrite if newFileName exist
			sendCommand("RNTO " + newFileName);

			if (retValue != 250)
			{
				throw new IOException(reply.Substring(4));
			}
		}

		///
		The ON the Create Directory A /// Remote the FTP Server. 
		/// 
		/// This is a directory created on the remote server function 
		public void mkdir (String dirName) 
		{ 
			IF (logined!) 
			{ 
				Login (); 
			} 
			sendCommand ( "MKD" + dirName); 


            IF (250 || retValue retValue == == 257) 
            { 

            } 
            the else 
            {
              the throw new new IOException (reply.Substring (. 4)); 
            } 
		} 

		/// 
		/// The ON the Delete Directory A Remote the FTP server. 
		/// 
		/// this is a deleted directory on the remote FTP server function 
		public void rmdir (String dirName) 
		{ 
			IF (! logined) 
			{
				Login (); 
			} 

			sendCommand ( "the RMD" + dirName); 

			IF (retValue = 250!) 
			{ 
				the throw new new IOException (reply.Substring (. 4)); 
			} 
		} 

		/// 
		/// The Current Working Directory Change The Remote ON server FTP. 
		/// 
		/// this is a function used to change the current working directory on the remote FTP server. 
		void the chdir public (String dirName) 
		{ 
			IF ( "." dirName.Equals ())  
			{
				return; 
			} 
			IF (logined!) 
			{ 
				Login (); 
			} 
			sendCommand ( "CWD" + dirName); 

			IF (! retValue = 250) 
			{ 
				new new IOException the throw (reply.Substring (. 4)); 
			}

			this.remotePath = dirName;
			Console.WriteLine("Current directory is " + remotePath);
		}

		///
		/// Close the FTP connection.
		/// 关闭远程服务器的FTP链接
		public void close()
		{
			if (clientSocket != null)
			{
				sendCommand("QUIT");
			}
			cleanup();
			Console.WriteLine("Closing...");
		}

		///
		/// Set debug mode.
		///
		///
		public void setDebug(Boolean debug)
		{
			this.debug = debug;
		}

		private void readReply()
		{
			mes = "";
			reply = readLine();
			retValue = Int32.Parse(reply.Substring(0, 3));
		}

		private void cleanup()
		{
			if (clientSocket != null)
			{
				clientSocket.Close();
				clientSocket = null;
			}
			logined = false;
		}

		private string readLine()
		{
			while (true)
			{
				bytes = clientSocket.Receive(buffer, buffer.Length, 0);
				mes += Default.GetString(buffer, 0, bytes);
				if (bytes < buffer.Length)
				{
					break;
				}
			}

			char[] seperator = {'\n'};
			string[] mess = mes.Split(seperator);
			if (mes.Length > 2)
			{
				mes = mess[mess.Length - 2];
			}
			else
			{
				mes = mess[0];
			}

			if (!mes.Substring(3, 1).Equals(" "))
			{
				return readLine();
			}

			if (debug)
			{
				for (int k = 0; k < mess.Length - 1; k++)
				{
					Console.WriteLine(mess[k]);
				}
			}
			return mes;
		}


		private void sendCommand(String command)
		{
			Byte[] cmdBytes = Encoding.Default.GetBytes((command + "\r\n").ToCharArray());
			clientSocket.Send(cmdBytes, cmdBytes.Length, 0);
			readReply();
		}


		//创建一个数据包 
		private Socket createDataSocket()
		{
			sendCommand("PASV");
			if (retValue != 227)
			{


				if (Char.IsDigit(ch))
						parts[partCount++] = Int32.Parse(buf);
						buf = "";
					}
					catch (Exception)
					{
						throw new IOException("Malformed PASV reply: " + reply);
					}
				}
			}

			string ipAddress = parts[0] + "." + parts[1] + "." + parts[2] + "." + parts[3];
			int port = (parts[4] << 8) + parts[5];

			Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
			s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 5000);

			IPEndPoint ep = new IPEndPoint(Dns.Resolve(ipAddress).AddressList[0], port);

			try
			{
				s.Connect(ep);
			}
			catch (Exception)
			{
				throw new IOException("Can't connect to remote   server");
			}
			return s;
		}


        
}
//调用
 public bool SaveFileToFTP(string ftppath, string filename)
        {
            
            bool result = System.IO.File.Exists(filename);
            if (result)
            {
                try
                {
                    FTPHelper ftpHelper = new FTPHelper(FTPIP, "", FTPUserName, FTPPassword, SysConvert.ToInt32(FTPPort));
                    foreach (string dir in ftppath.Split('/').ToArray())
                    {
                        if (string.IsNullOrEmpty(dir))
                        {
                            continue;
                        }
                        bool isContinue = false;

                        string[] ftpfileslist = ftpHelper.getFileList();
                        for (int i = 0; i < ftpfileslist.Length; i++)
                        {
                            string tempStr = ftpfileslist[i].Trim().Replace("\\r", "");
                            if (string.IsNullOrEmpty(tempStr))
                            {
                                continue;
                            }
                            string[] ftpDirInfo = tempStr.Split(' ');
                            //log.Info(tempStr);
                            if (tempStr.ToLower().Contains("<dir>") || ftpDirInfo[0].Contains("dr"))
                            {
                                if (ftpDirInfo[ftpDirInfo.Length - 1] == dir)
                                {
                                    ftpHelper.chdir(dir);
                                    isContinue = true;
                                    break;
                                }
                                continue;
                            }
                        }
                        if (!isContinue)
                        {
                            try
                            {
                                ftpHelper.mkdir(dir);
                            }
                            catch
                            {
                            }
                            ftpHelper.chdir(dir);
                        }
                    }
                    ftpHelper.upload(filename);
                }
                catch (Exception ex)
                {
                    
                    result = false;
                }
            }
            return result;
        }

  

  

Guess you like

Origin www.cnblogs.com/ZeroSunny/p/11302184.html