65.9K
CodeProject is changing. Read more.
Home

Simple FTP File Application

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.20/5 (3 votes)

Sep 28, 2019

CPOL

2 min read

viewsIcon

5690

downloadIcon

401

This article demonstrates how to send file to server via FTP routine.

Introduction

When your application needs to send a file to the server via FTP, you don't need a third party DLL, just a module, which allows you to send a file directly to the server on a command line. In this article, we will show how it is possible to upload a file via FTP and upload progress through a ProgressBar and show status progress in ListBox control.

The purpose of this article is to introduce developers to the basic routine of sending files via FTP, but it opens up numerous possibilities for the implementation of new routines, which may even create an FTP application.

Another important issue to be highlighted in this article refers to resources. The project uses five image (icons) in the resource files. These are made available in the source code file.

Requirements

  • .NET Framework 4.5 or higher
  • System.Windows.Forms
  • System.Net
  • System.Drawing

Code

The code is divided between the Module and the Form. In the module, there are all necessary routines for simple file upload to the Server via FTP.

Module

The heart or core of the application is the mFTP module, which contains the Routines and Functions needed for full operation. In this module, we have a Friend Class (named Xrefs), which allows the insertion of text, image (16x16 icon, but this dimension can be changed) and changes the color of the text, to give the user visual information and draw attention. The following colors were used in this article to inform the user of the status:

  • Blue = Low Attention Status
  • Black = Neutral Status
  • ForestGreen = Good Status
  • DeepSkyBlue = Medium Attention Status
  • DarkGreen = Excellent Status
  • Red = Error performing operation

In addition to Friend Class, we have two Subs (pStatus e UploadFile) and one Function ConvertBytes.

Imports System.Net
Imports System.IO

Module mFTP
    Friend Class Xrefs
        'This Friendly Class allows you to add text to images in ComboBox and ListBox items.
        Public Property Text As String
        Public Property Image As Image
        Public Property Color As System.Drawing.Brush
        Public Sub New()
            'Create new Instance with nothing value for all variables
            Me.New(Nothing, Nothing, Nothing)
        End Sub
        Public Sub New(ByVal Text As String)
            'Create new Instance with for Text variable
            Me.New(Text, Nothing, Nothing)
        End Sub
        'Create new Instance with value for all variables (Text, Image and Color)
        Public Sub New(ByVal Text As String, _
            ByVal Image As Image, ByVal Color As System.Drawing.Brush)
            Me.Text = Text
            Me.Image = Image
            Me.Color = Color
        End Sub
    End Class

    Public Sub UploadFile(ByVal sFileName As String, _
        ByVal sFTPHost As String, ByVal sFTPUploadPath As String, _
                          ByVal sFTPUserName As String, ByVal sFTPPwd As String, _
                          ByRef oProgressBar As ProgressBar, ByRef oListBox As ListBox)
        Dim oFileInfo As New System.IO.FileInfo(sFileName)

        Try
            Dim sUri As String
            'Checks if sFTPHost and sFTPUploadPath Variables ends with 
            '"/" and create a correct sUri variable, to set in Uri object
            If sFTPHost.EndsWith("/") = True And _
                sFTPUploadPath.EndsWith("/") = True Then
                sUri = sFTPHost & sFTPUploadPath & _
                    System.IO.Path.GetFileName(sFileName.ToString)
            ElseIf sFTPHost.EndsWith("/") = True And _
                sFTPUploadPath.EndsWith("/") = False Then
                sUri = sFTPHost & sFTPUploadPath & "/" & _
                    System.IO.Path.GetFileName(sFileName.ToString)
            ElseIf sFTPHost.EndsWith("/") = False And _
                sFTPUploadPath.EndsWith("/") = False Then
                sUri = sFTPHost & "/" & sFTPUploadPath & "/" & _
                     System.IO.Path.GetFileName(sFileName.ToString)
            End If
            'Create FtpWebRequest object from the Uri provided and set the object Type
            Dim oFtpWebRequest As System.Net.FtpWebRequest = _
                CType(System.Net.FtpWebRequest.Create_
                (New Uri(sUri)), System.Net.FtpWebRequest)

            'Insert Item in Listbox
            pStatus(oListBox, "Connecting to the server: " & _
                sFTPHost, My.Resources.connect, Brushes.Blue)

            'Insert Item in Listbox
            pStatus(oListBox, String.Format("Host: {0} - Username: {1} - Password: {2}", _
                sFTPHost, sFTPUserName, "******"), My.Resources.connect, Brushes.DarkBlue)

            'Informs to oFtpWebRequest Object, the WebPermission Credentials
            oFtpWebRequest.Credentials = _
                    New System.Net.NetworkCredential(sFTPUserName, sFTPPwd)

            ' The default KeepAlive value is True, 
            ' but the control connection is not closed after a command is executed.
            oFtpWebRequest.KeepAlive = False

            'Insert Item in Listbox
            pStatus(oListBox, "Starting the connection...", _
                             My.Resources.accept, Brushes.Black)

            Application.DoEvents() : Application.DoEvents()

            'Set timeout to oFtpWebRequest Object for 30 seconds or more
            oFtpWebRequest.Timeout = 30000

            'Insert Item in Listbox
            pStatus(oListBox, "Connection accepted...", _
                    My.Resources.accept, Brushes.ForestGreen)

            Application.DoEvents() : Application.DoEvents()

            'Insert Item in Listbox
            pStatus(oListBox, "Sending the file: '" & _
            System.IO.Path.GetFileName(sFileName.ToString) & "'", _
            My.Resources.database_lightning, Brushes.Black)
            'Show information about filesize in KB, MB, GB
            'Insert Item in Listbox
            pStatus(oListBox, "Size: '" & _
            ConvertBytes(oFileInfo.Length) & "'", _
                         My.Resources.database_lightning, Brushes.Black)

            Application.DoEvents() : Application.DoEvents()

            ' Specify to oFtpWebRequest the command that will be executed.
            oFtpWebRequest.Method = System.Net.WebRequestMethods.Ftp.UploadFile

            ' Specify the data transfer type. The binary is recommended
            oFtpWebRequest.UseBinary = True

            'Use Passive mode
            oFtpWebRequest.UsePassive = True

            ' Informs the server about the size , in bytes, of the uploaded file
            oFtpWebRequest.ContentLength = oFileInfo.Length

            ' The buffer size is set to 2kb, 
            ' but you can change to 1024 (more slow) 
            ' or change to 4096 if your server permits
            Dim buffLength As Integer = 2048
            Dim buff(buffLength - 1) As Byte

            pStatus(oListBox, "Sending the file...", _
            My.Resources.transmit_blue, Brushes.DeepSkyBlue)

            'Opens a file stream 
            '(using System.IO.FileStream) to read the file to be uploaded
            Dim oFileStream As System.IO.FileStream = oFileInfo.OpenRead()
            Application.DoEvents() : Application.DoEvents()

            'Stream to which the file to be uploaded is written on the Server Path
            Dim oStream As System.IO.Stream = oFtpWebRequest.GetRequestStream()

            'Read from the file stream 2kb at a time, 
            'but if you change the buffer value the size change too
            Dim contentLen As Integer = oFileStream.Read(buff, 0, buffLength)
            Application.DoEvents() : Application.DoEvents()

            oProgressBar.Maximum = oFileInfo.Length
            Application.DoEvents() : Application.DoEvents()
            ' Till Stream content ends
            Do While contentLen <> 0
                ' Write Content from the file stream to the FTP Upload Stream
                oStream.Write(buff, 0, contentLen)
                contentLen = oFileStream.Read(buff, 0, buffLength)
                oProgressBar.Value += contentLen
                Application.DoEvents() : Application.DoEvents()
            Loop

            ' Dispose and Close the file Stream and the Request Stream
            oStream.Close()
            oStream.Dispose()
            oFileStream.Close()
            oFileStream.Dispose()

            'Insert Item in Listbox
            pStatus(oListBox, "Upload successfully!", _
                    My.Resources.accept, Brushes.DarkGreen)
        Catch ex As Exception
            MessageBox.Show(ex.ToString, My.Application.Info.Title, _
                MessageBoxButtons.OK, MessageBoxIcon.Error)
            'Insert Item in Listbox
            pStatus(oListBox, ex.Message, My.Resources.exclamation, Brushes.Red)
        Finally
            'Set zero value to ProgressBar object
            oProgressBar.Value = 0
        End Try
    End Sub
    ''' <summary>
    ''' Displays FTP status, on demand and according 
    ''' to information passed in Sub UploadFile
    ''' </summary>
    ''' <param name="olbox">Listbox control 
    ''' that will receive the text (sText), image (img) and text color lColor</param>
    ''' <param name="sText">Text to be displayed 
    ''' on item inserted in olbox control</param>
    ''' <param name="img">Image (16 x 16 px) 
    ''' to be displayed on item inserted in olbox control</param>
    ''' <param name="lColor">Text Color (ForeColor), 
    ''' which will be set to the text entered in the olbox control item.</param>
    ''' <remarks></remarks>
    Public Sub pStatus(ByRef olbox As ListBox, ByVal sText As String, _
        img As System.Drawing.Bitmap, lColor As System.Drawing.Brush)
        Dim oXref As Xrefs
        oXref = New Xrefs(sText, img, lColor)
        olbox.Items.Add(oXref)
    End Sub
    ''' <summary>
    ''' Converter Filesize of Bytes to KB or MB or GB
    ''' </summary>
    ''' <param name="Bytes">File Size in bytes</param>
    ''' <returns>Return String value</returns>

    Public Function ConvertBytes(ByVal Bytes As Long) As String
        ' Converts bytes into a readable "1.44 MB", etc. string
        If Bytes >= 1073741824 Then 'if filesize higher than 1073741824 bytes,
                                    ' convert to GB
            Return Format(Bytes / 1024 / 1024 / 1024, "#0.00") _
                & " GB"
        ElseIf Bytes >= 1048576 Then 'if filesize higher than 1048576 bytes convert to KB
            Return Format(Bytes / 1024 / 1024, "#0.00") & " MB"
        ElseIf Bytes >= 1024 Then
            Return Format(Bytes / 1024, "#0.00") & " KB"
        ElseIf Bytes > 0 And Bytes < 1024 Then 'if filesize minor than 1024 bytes 
                                               'isnot convert
            Return Fix(Bytes) & " Bytes"
        Else
            Return "0 Bytes"
        End If
    End Function
End Module

Form

The form named frmFTP has several objects, among them Label, TextBox, ProgressBar, ListBox.

Imports System.IO

Public Class frmFTP

    Private Sub frmFTP_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Text = String.Format("{0} v {1}", _
            My.Application.Info.Title, My.Application.Info.Version.ToString)
    End Sub

    Private Sub btnOpenFile_Click(sender As Object, e As EventArgs) _
        Handles btnOpenFile.Click
        Dim oDlg As New OpenFileDialog
        With oDlg
            .Title = "Open file to Upload"
            .Filter = "All files (*.*)|*.*"
            .ShowReadOnly = False
            If .ShowDialog = Windows.Forms.DialogResult.OK Then
                txtFileUpload.Text = .FileName
            End If
        End With
    End Sub

    Private Sub btnClose_Click(sender As Object, e As EventArgs) Handles btnClose.Click
        Application.ExitThread()
        Application.Exit()
    End Sub

    Private Sub btnUploadFile_Click(sender As Object, e As EventArgs) _
        Handles btnUploadFile.Click
        'Checks if all required fields have been filled
        If CheckField(txtFTPHost, "FTP Host") = False Then Exit Sub
        If CheckField(txtUsername, "FTP Username") = False Then Exit Sub
        If CheckField(txtPassword, "FTP Password") = False Then Exit Sub
        If CheckField(txtPathUpload, "FTP Path Upload") = False Then Exit Sub
        If CheckField(txtFileUpload, "FTP File Upload") = False Then Exit Sub
        Try
            'Checks if FileUpload Exists
            If File.Exists(txtFileUpload.Text) = False Then
                MessageBox.Show("The file you are trying to upload via FTP _
                does not exist or has been moved!", My.Application.Info.Title, _
                MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                Exit Sub
            End If
            lstStatus.Items.Clear()
            UploadFile(txtFileUpload.Text, txtFTPHost.Text, _
            txtPathUpload.Text, txtUsername.Text, txtPassword.Text, pBar, lstStatus)

        Catch ex As Exception
            MessageBox.Show(ex.ToString, My.Application.Info.Title, _
            MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
        End Try
    End Sub
    Private Sub lstStatus_DrawItem(sender As Object, e As DrawItemEventArgs) _
            Handles lstStatus.DrawItem
        Try
            If e.Index > -1 Then
                'Create instance of the oXref Class with lstStatus item
                Dim oXref As Xrefs = lstStatus.Items(e.Index)
                e.DrawBackground()
                'Draw image in Listbox Item
                e.Graphics.DrawImage(oXref.Image, e.Bounds.Left, e.Bounds.Top)
                'Draw text (string) in Listbox Item
                e.Graphics.DrawString(oXref.Text, Me.Font, oXref.Color, _
                e.Bounds.Left + 20, e.Bounds.Top)
            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message, My.Application.Info.Title, _
                MessageBoxButtons.OK, MessageBoxIcon.Hand)
        End Try

    End Sub
    Public Function CheckField(ByRef ctl As Control, ByVal sCampo As String) As Boolean
        Dim bResult As Boolean = False
        'check Object type
        If TypeOf ctl Is TextBox Then
            If Trim(ctl.Text) <> String.Empty Then bResult = True
        End If
        If TypeOf ctl Is ComboBox Then
            If Trim(ctl.Text) <> String.Empty Then bResult = True
        End If
        If TypeOf ctl Is RichTextBox Then
            If Trim(ctl.Text) <> String.Empty Then bResult = True
        End If
        'Check bResult Variable 
        'if False, Show MessageBox and change backcolor of the control to Coral
        'if True, change the BackColor Property 
        'of the control to DEfaul (White or Transparent)
        If bResult = False Then
            MessageBox.Show("The field '" & sCampo & "' _
                can't be empty!", My.Application.Info.Title, _
                MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            ctl.BackColor = Color.Coral
            ctl.Focus()
            Return bResult
        Else
            If TypeOf ctl Is Label Then
                ctl.BackColor = Color.Transparent
            Else
                ctl.BackColor = Color.White
            End If
            Return bResult
        End If
    End Function

End Class

Screenshot

The application has a form called frmFTP, whose screen is shown below:

Points of Interest

In this article, you can understand how to send one file at a time to a server via FTP. In this article, it is still possible to understand some properties of the FTPWebRequest class and the use of local Stream and its association with WebStream, to write the file on the server, byte by byte. It is also possible to understand the upload of the file, showing progress and the creation of a Status log, so that the user can follow the upload of the file in a step by step manner.

History

  • 2019-09-27: Release version

Reference