FileUtil.vb Imports System Imports System.Net Imports System.IO Imports System.Text Imports System.Net.Sockets Public Class FTPUtil Private mstrRemoteHost As String Private mstrRemotePath As String Private mstrRemoteUser As String Private mstrRemotePassword As String Private mintRemotePort As Integer Private mintBytes As Integer Private mobjClientSocket As Socket Private mintRetValue As Integer Private mblnLoggedIn As Boolean Private mstrMes As String Private mstrReply As String Private mstrMessageString As String 'Set the size of the packet that is used to read and to write data to the FTP server 'to the following specified size. Private Const BLOCK_SIZE As Integer = 512 Private mbytBuff(BLOCK_SIZE) As Byte Private ASCII As Encoding = Encoding.ASCII Private mblnFlg As Boolean Public Sub New(ByVal sRemoteHost As String, _ ByVal sRemotePath As String, _ ByVal sRemoteUser As String, _ ByVal sRemotePassword As String, _ ByVal iRemotePort As Integer) mstrRemoteHost = sRemoteHost mstrRemotePath = sRemotePath mstrRemoteUser = sRemoteUser mstrRemotePassword = sRemotePassword mstrMessageString = "" mintRemotePort = 21 mblnLoggedIn = False mobjClientSocket = _ New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) Dim objEndPoint As New IPEndPoint(Dns.GetHostEntry(mstrRemoteHost).AddressList(0), mintRemotePort) 'Connect To FTP Server Try mobjClientSocket.Connect(objEndPoint) Catch ex As Exception MessageString = mstrReply Throw New IOException("Cannot connect to remote server") End Try ReadReply() If (mintRetValue <> 220) Then CloseConnection() MessageString = mstrReply Throw New IOException(mstrReply.Substring(4)) End If End Sub Public ReadOnly Property Connected() As Boolean Get Return mblnFlg End Get End Property Public Property RemotePath() As String Get Return mstrRemotePath End Get Set(ByVal Value As String) mstrRemotePath = Value End Set End Property Public Property MessageString() As String Get Return mstrMessageString End Get Set(ByVal Value As String) mstrMessageString = Value End Set End Property Public Sub Login() 'Send User SendCommand("USER " & mstrRemoteUser) If (Not (mintRetValue = 331 Or mintRetValue = 230)) Then Cleanup() MessageString = mstrReply Throw New IOException(mstrReply.Substring(4)) End If 'Send Password If (mintRetValue <> 230) Then SendCommand("PASS " & mstrRemotePassword) If (Not (mintRetValue = 230 Or mintRetValue = 202)) Then Cleanup() MessageString = mstrReply Throw New IOException(mstrReply.Substring(4)) End If End If mblnLoggedIn = True 'Change Directory ChangeDirectory(mstrRemotePath) End Sub Public Function GetFileSize(ByVal sFileName As String) As Long Dim size As Long 'Get File Size SendCommand("SIZE " & sFileName) size = 0 If (mintRetValue = 213) Then size = Int64.Parse(mstrReply.Substring(4)) Else MessageString = mstrReply Throw New IOException(mstrReply.Substring(4)) End If Return size End Function Public Sub DownloadFile(ByVal strArgFileName As String, _ ByVal blnArgBinary As Boolean, _ ByVal blnArgNotExistsErr As Boolean) SetBinaryMode(blnArgBinary) If (Not (File.Exists(strArgFileName))) Then Dim objStream As Stream objStream = File.Create(strArgFileName) objStream.Close() End If Dim objOutFileStream As FileStream Dim objSock As Socket Dim lngOffset As Long objOutFileStream = New FileStream(strArgFileName, FileMode.Open) objSock = CreateDataSocket() lngOffset = 0 If (blnArgBinary) Then lngOffset = objOutFileStream.Length If (lngOffset > 0) Then SendCommand("REST " & lngOffset) If (mintRetValue <> 350) Then lngOffset = 0 End If End If Dim lngNPos As Long If (lngOffset > 0) Then lngNPos = objOutFileStream.Seek(lngOffset, SeekOrigin.Begin) End If End If SendCommand("RETR " & strArgFileName) If mintRetValue <> 550 Then If (Not (mintRetValue = 150 Or mintRetValue = 125 Or mintRetValue = 226)) Then objOutFileStream.Close() MessageString = mstrReply Throw New IOException(mstrReply.Substring(4)) End If Do While (True) Array.Clear(mbytBuff, 0, mbytBuff.Length) mintBytes = objSock.Receive(mbytBuff, mbytBuff.Length, 0) objOutFileStream.Write(mbytBuff, 0, mintBytes) If (mintBytes <= 0) Then Exit Do End If Loop objOutFileStream.Close() If (objSock.Connected) Then objSock.Close() End If Else If blnArgNotExistsErr Then objOutFileStream.Close() MessageString = mstrReply Throw New IOException(mstrReply.Substring(4)) End If End If End Sub Public Sub UploadFile(ByVal strArgFileName As String, _ ByVal blnArgBinary As Boolean) Dim objSock As Socket Dim lngOffset As Long Dim objInFileStream As FileStream Dim blnFileNotFound As Boolean objSock = CreateDataSocket() lngOffset = 0 If (blnArgBinary) Then Try SetBinaryMode(True) lngOffset = GetFileSize(strArgFileName) Catch ex As Exception lngOffset = 0 End Try End If If (lngOffset > 0) Then SendCommand("REST " & lngOffset) If (mintRetValue <> 350) Then lngOffset = 0 End If End If SendCommand("STOR " & Path.GetFileName(strArgFileName)) If (Not (mintRetValue = 125 Or mintRetValue = 150)) Then MessageString = mstrReply Throw New IOException(mstrReply.Substring(4)) End If blnFileNotFound = False If (File.Exists(strArgFileName)) Then objInFileStream = New FileStream(strArgFileName, FileMode.Open) If (lngOffset <> 0) Then objInFileStream.Seek(lngOffset, SeekOrigin.Begin) End If mintBytes = objInFileStream.Read(mbytBuff, 0, mbytBuff.Length) Do While (mintBytes > 0) objSock.Send(mbytBuff, mintBytes, 0) mintBytes = objInFileStream.Read(mbytBuff, 0, mbytBuff.Length) Loop objInFileStream.Close() Else blnFileNotFound = True End If If (objSock.Connected) Then objSock.Close() End If If (blnFileNotFound) Then MessageString = mstrReply Throw New IOException("The file: " & strArgFileName & " was not found." & _ " Cannot upload the file to the FTP site.") End If ReadReply() If (Not (mintRetValue = 226 Or mintRetValue = 250)) Then MessageString = mstrReply Throw New IOException(mstrReply.Substring(4)) End If End Sub Public Function DeleteFile(ByVal strArgFileName As String) As Boolean Dim blnResult As Boolean blnResult = True SendCommand("DELE " & strArgFileName) If (mintRetValue <> 250 And mintRetValue <> 550) Then blnResult = False MessageString = mstrReply End If Return blnResult End Function Public Function RenameFile(ByVal strArgOldFileNm As String, _ ByVal strArgNewFileNm As String) As Boolean Dim blnResult As Boolean blnResult = True SendCommand("RNFR " & strArgOldFileNm) If (mintRetValue <> 350) Then MessageString = mstrReply Throw New IOException(mstrReply.Substring(4)) End If SendCommand("RNTO " & strArgNewFileNm) If (mintRetValue <> 250) Then MessageString = mstrReply Throw New IOException(mstrReply.Substring(4)) End If Return blnResult End Function Public Function CreateDirectory(ByVal strArgDirPath As String) As Boolean Dim blnResult As Boolean blnResult = True SendCommand("MKD " & strArgDirPath) If (mintRetValue <> 257) Then blnResult = False MessageString = mstrReply End If Return blnResult End Function Public Function RemoveDirectory(ByVal strArgDirPath As String) As Boolean Dim blnResult As Boolean blnResult = True SendCommand("RMD " & strArgDirPath) If (mintRetValue <> 250) Then blnResult = False MessageString = mstrReply End If Return blnResult End Function Public Function ChangeDirectory(ByVal strArgDirPath As String) As Boolean Dim blnResult As Boolean blnResult = True If (strArgDirPath.Equals(".")) Then Exit Function End If SendCommand("CWD " & strArgDirPath) If (mintRetValue <> 250) Then blnResult = False MessageString = mstrReply End If Me.mstrRemotePath = strArgDirPath Return blnResult End Function Public Sub CloseConnection() If (Not (mobjClientSocket Is Nothing)) Then SendCommand("QUIT") End If Cleanup() End Sub Private Sub SendCommand(ByVal strArgCmd As String) Dim strCmd As String = strArgCmd & ControlChars.CrLf Dim cmdbytes As Byte() = Encoding.GetEncoding("Shift_JIS").GetBytes(strCmd) mobjClientSocket.Send(cmdbytes, cmdbytes.Length, 0) If strArgCmd <> "QUIT" Then ReadReply() End If End Sub Private Function CreateDataSocket() As Socket Dim intPortNo As Integer Dim strIpData As String SendCommand("PASV") If (mintRetValue <> 227) Then MessageString = mstrReply Throw New IOException(mstrReply.Substring(4)) End If Dim intIdx1 As Integer Dim intIdx2 As Integer intIdx1 = mstrReply.IndexOf("(") intIdx2 = mstrReply.IndexOf(")") strIpData = mstrReply.Substring(intIdx1 + 1, intIdx2 - intIdx1 - 1) Dim intLength As Integer Dim intPartCount As Integer Dim strBuff As String intLength = strIpData.Length intPartCount = 0 strBuff = "" Dim intLoop As Integer Dim intParts(6) As Integer For intLoop = 0 To ((intLength - 1) And CType(intPartCount <= 6, Integer)) Dim chrBuffPart As Char chrBuffPart = Char.Parse(strIpData.Substring(intLoop, 1)) If (Char.IsDigit(chrBuffPart)) Then strBuff += chrBuffPart ElseIf (chrBuffPart <> ",") Then MessageString = mstrReply Throw New IOException("Malformed PASV reply: " & mstrReply) End If If ((chrBuffPart = ",") Or (intLoop + 1 = intLength)) Then Try intParts(intPartCount) = Integer.Parse(strBuff) intPartCount += 1 strBuff = "" Catch ex As Exception MessageString = mstrReply Throw New IOException("Malformed PASV reply: " & mstrReply) End Try End If Next Dim strIpAddress As String strIpAddress = intParts(0) & "." & intParts(1) & "." & intParts(2) & "." & intParts(3) intPortNo = intParts(4) << 8 intPortNo = intPortNo + intParts(5) Dim objSock As Socket Dim objEndPoint As IPEndPoint objSock = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) objEndPoint = New IPEndPoint(Dns.GetHostEntry(strIpAddress).AddressList(0), intPortNo) Try objSock.Connect(objEndPoint) Catch ex As Exception MessageString = mstrReply Throw New IOException("Cannot connect to remote server") mblnFlg = False End Try mblnFlg = True Return objSock End Function Private Sub SetBinaryMode(ByVal blnArgBinary As Boolean) If (blnArgBinary) Then 'binary SendCommand("TYPE I") Else 'ASCII SendCommand("TYPE A") End If If (mintRetValue <> 200) Then MessageString = mstrReply Throw New IOException(mstrReply.Substring(4)) End If End Sub Private Sub ReadReply() mstrMes = "" mstrReply = ReadLine() mintRetValue = Integer.Parse(mstrReply.Substring(0, 3)) End Sub Private Function ReadLine(Optional ByVal blnArgClearMes As Boolean = False) As String If (blnArgClearMes) Then mstrMes = "" End If Do While (True) Array.Clear(mbytBuff, 0, BLOCK_SIZE) mintBytes = mobjClientSocket.Receive(mbytBuff, mbytBuff.Length, 0) mstrMes += ASCII.GetString(mbytBuff, 0, mintBytes) If (mintBytes < mbytBuff.Length) Then Exit Do End If Loop Dim strMess() As String Dim chrSeperator As Char = ControlChars.Lf strMess = mstrMes.Split(chrSeperator) If (mstrMes.Length > 2) Then mstrMes = strMess(strMess.Length - 2) Else mstrMes = strMess(0) End If If (Not (mstrMes.Substring(3, 1).Equals(" "))) Then Return ReadLine(True) End If Return mstrMes End Function Private Sub Cleanup() If Not (mobjClientSocket Is Nothing) Then mobjClientSocket.Close() mobjClientSocket = Nothing End If mblnLoggedIn = False End Sub End Class