65.9K
CodeProject 正在变化。 阅读更多。
Home

简单的 FTP 文件应用程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.20/5 (3投票s)

2019年9月28日

CPOL

2分钟阅读

viewsIcon

5969

downloadIcon

426

本文演示了如何通过 FTP 例程将文件发送到服务器。

引言

当您的应用程序需要通过 FTP 将文件发送到服务器时,您不需要第三方 DLL,只需要一个模块,该模块允许您直接通过命令行将文件发送到服务器。 在本文中,我们将展示如何通过 FTP 上传文件,并通过 ProgressBar 显示上传进度,并在 ListBox 控件中显示状态进度。

本文的目的是向开发人员介绍通过 FTP 发送文件的基本例程,但它为实施新的例程打开了无数的可能性,甚至可以创建一个 FTP 应用程序。

本文中需要重点说明的另一个重要问题是资源。 该项目在资源文件中使用了五张图像(图标)。 这些图像在源代码文件中提供。

要求

  • .NET Framework 4.5 或更高版本
  • System.Windows.Forms
  • System.Net
  • System.Drawing

代码

代码分为模块和窗体。 在模块中,包含所有通过 FTP 将文件上传到服务器所需的例程。

模块

该应用程序的核心是 mFTP 模块,其中包含完成操作所需的所有例程和函数。 在此模块中,我们有一个 Friend 类(名为 Xrefs),它允许插入文本、图像(16x16 图标,但此尺寸可以更改)并更改文本颜色,以便向用户提供视觉信息并引起注意。 在本文中使用了以下颜色来告知用户状态

  • 蓝色 = 低关注度状态
  • 黑色 = 中性状态
  • 森林绿 = 良好状态
  • 天蓝色 = 中等关注度状态
  • 深绿色 = 优秀状态
  • 红色 = 执行操作时出错

除了 Friend Class 之外,我们还有两个 SubpStatusUploadFile)和一个 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

表单

名为 frmFTP 的窗体有几个对象,其中包括 LabelTextBoxProgressBarListBox

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

屏幕截图

该应用程序有一个名为 frmFTP 的窗体,其屏幕如下所示

关注点

在本文中,您可以了解如何一次将一个文件通过 FTP 发送到服务器。 在本文中,还可以了解 FTPWebRequest 类的一些属性以及本地 Stream 的使用及其与 WebStream 的关联,以便逐字节将文件写入服务器。 还可以了解文件的上传、显示进度以及创建状态日志,以便用户可以逐步跟踪文件的上传情况。

历史

  • 2019-09-27:发布版本

参考

© . All rights reserved.