zoukankan      html  css  js  c++  java
  • .NET FTP上传文件

    帮助类 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)
    		{
    			this.remoteUser = remoteUser;
    		}
    
    		///
    		/// Set the password to user for logging into the remote server.
    		///
    		/// Password
    		public void setRemotePass(string remotePass)
    		{
    			this.remotePass = remotePass;
    		}
    
    		///
    		/// 从文件系统中返回一个文件列表。在string()函数中返回文件。.
    		///
    		///
    		///
    		public string[] getFileList(string mask)
    		{
    			if (!logined)
    			{
    				login();
    			}
    
    			Socket cSocket = createDataSocket();
    
    			sendCommand("NLST " + mask);
    
    			if (!(retValue == 150 || retValue == 125))
    			{
    				throw new IOException(reply.Substring(4));
    			}
    
    			mes = "";
    			Thread.Sleep(700);
    
    			while (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);
    
    			chdir(remotePath);
    		}
    
    		///
    		/// 如果模式值为真,对下载设置为二进制模式。否则,设置为Default模式
    		/// Else, set Ascii mode.
    		///
    		///
    		public void setBinaryMode(Boolean mode)
    		{
    			if (mode)
    			{
    				sendCommand("TYPE I");
    			}
    			else
    			{
    				sendCommand("TYPE A");
    			}
    			if (retValue != 200)
    			{
    				throw new IOException(reply.Substring(4));
    			}
    		}
    
    		///
    		/// Download a file to the Assembly's local directory,
    		/// keeping the same file name.
    		///
    		/// 向配置好的本地目录下载一个文件。保持文件名一样。
    		public void download(string remFileName)
    		{
    			download(remFileName, "", false);
    		}
    
    		///
    		/// Download a remote file to the Assembly's local directory,
    		/// keeping the same file name, and set the resume flag.
    		///
    		///
    		/// 向一个配置好的本地文件夹下载一个远程文件。保持文件名一样。
    		public void download(string remFileName, Boolean resume)
    		{
    			download(remFileName, "", resume);
    		}
    
    		///
    		/// Download a remote file to a local file name which can   include
    		/// a path. The local file name will be created or overwritten,
    		/// but the path must exist.
    		///
    		/// 对本地文件名下载一个远程文件。你必须包含一个路径。
    		/// 本地文件名将会创建或者将会被重写,但是路径必须存在。
    		public void download(string remFileName, string locFileName)
    		{
    			download(remFileName, locFileName, false);
    		}
    
    		///
    		/// Download a remote file to a local file name which can include
    		/// a path, and set the resume flag. The local file name will be
    		/// created or overwritten, but the path must exist.
    		///
    		/// 对一个本地文件名下载一个远程文件。你必须包含一个路径。
    		/// 设置恢复标志。本地文件名将会被创建或被重写,但是本地路径必须存在。
    		///
    		public void download(string remFileName, string locFileName, Boolean resume)
    		{
    			if (!logined)
    			{
    				login();
    			}
    			setBinaryMode(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)
    			{
    				bytes = cSocket.Receive(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 == 226 || retValue == 250))
    			{
    				throw new IOException(reply.Substring(4));
    			}
    		}
    
    		///
    		/// Upload a System.IO.File.
    		///
    		/// 这是一个从你的本地硬盘上向你的FTP文件夹中上载文件的函数
            public void upload(string fileName)
    		{
    			upload(fileName, false);
    		}
    
    		///
    		/// Upload a file and set the resume flag.
    		///
    		///
    		/// 这是一个从你的本地硬盘上向你的FTP网页上上载的函数和设置恢复标志
    		public void upload(string fileName, Boolean resume)
    		{
    			if (!logined)
    			{
    				login();
    			}
    			Socket cSocket = createDataSocket();
    			long offset = 0;
    
    			if (resume)
    			{
    				try
    				{
    					setBinaryMode(true);
    					offset = getFileSize(fileName);
    				}
    				catch (Exception)
    				{
    					offset = 0;
    				}
    			}
    
    			if (offset > 0)
    			{
    				sendCommand("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));
    			}
    		}
    
    		///
    		/// Create a directory on the remote FTP server.
    		///
    		/// 这是一个在远程服务器上创建目录的函数
    		public void mkdir(string dirName)
    		{
    			if (!logined)
    			{
    				login();
    			}
    			sendCommand("MKD " + dirName);
    
    
                if (retValue == 250 || retValue == 257)
                {
    
                }
                else
                {
                  throw new IOException(reply.Substring(4));
                }
    		}
    
    		///
    		/// Delete a directory on the remote FTP server.
    		///
    		/// 这是一个在远程FTP服务器上删除目录的函数
    		public void rmdir(string dirName)
    		{
    			if (!logined)
    			{
    				login();
    			}
    
    			sendCommand("RMD " + dirName);
    
    			if (retValue != 250)
    			{
    				throw new IOException(reply.Substring(4));
    			}
    		}
    
    		///
    		/// Change the current working directory on the remote FTP   server.
    		///
    		/// 这是一个用来在远程FTP服务器上改变当前工作目录的函数。
    		public void chdir(string dirName)
    		{
    			if (dirName.Equals("."))
    			{
    				return;
    			}
    			if (!logined)
    			{
    				login();
    			}
    			sendCommand("CWD " + dirName);
    
    			if (retValue != 250)
    			{
    				throw new IOException(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)
    			{
    				throw new IOException(reply.Substring(4));
    			}
    
    			int index1 = reply.IndexOf('(');
    			int index2 = reply.IndexOf(')');
    			string ipData = reply.Substring(index1 + 1, index2 - index1 - 1);
    			int[] parts = new int[6];
    			int len = ipData.Length;
    			int partCount = 0;
    			string buf = "";
    
    			for (int i = 0; i < len && partCount <= 6; i++)
    			{
    				char ch = Char.Parse(ipData.Substring(i, 1));
    				if (Char.IsDigit(ch))
    					buf += ch;
    				else if (ch != ',')
    				{
    					throw new IOException("Malformed PASV reply: " + reply);
    				}
    				if (ch == ',' || i + 1 == len)
    				{
    					try
    					{
    						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;
            }
    

      

      

  • 相关阅读:
    剑指Offer-用两个栈实现队列
    剑指Offer-从尾到头打印链表
    滑动门技术实现
    解决keil5中文注释乱码方法
    faker数据填充详解
    redis在微博与微信等互联网应用笔记
    JDBC插入中文数据出现?号地解决问题
    idea配置less自动编译
    idea使用Vue的v-bind,v-on报错
    idea 代码部分格式化
  • 原文地址:https://www.cnblogs.com/ZeroSunny/p/11302184.html
Copyright © 2011-2022 走看看