Avatar billede jens_k Nybegynder
04. januar 2005 - 10:09 Der er 24 kommentarer og
1 løsning

Overførsel af filer/mapper til FTP Server.

Hej,

Jeg ønsker at lave et lille program som skal kopiere nogle mappe/filer til min FTP Server, jeg vil bruge det som et slags automatisk backup som så skal kører hver aften. (Jeg har tænkt mig at starte det ved hjælp af STARTAT).

Det jeg gerne vil, er at jeg laver en tekstfil som indeholder f.eks:

c:\dokumenter\
c:\billeder\
c:\vigtig.txt

Det som "mit" program så skal gøre er at uploade disse mapper/filer som står i denne tekst fil til min FTP.

Der behøves ikke at være noget visuelt i programmet, det vigtigste er bare at den uploader filerne i det jeg executer programmet.

Nogen der kan hjælpe mig med hvordan jeg laver sådan et program?

Mvh

Jens_K
Avatar billede arne_v Ekspert
04. januar 2005 - 10:35 #1
Du skal have fat i et FTP library.

Du kan finde noget på nettet.

Ellers så har jeg også noget kode.
Avatar billede arne_v Ekspert
04. januar 2005 - 10:35 #2
Imports System
Imports System.IO
Imports System.Text
Imports System.Net.Sockets
Imports System.Threading

Public Class FtpClient
    Private ctrl As TcpClient
    Private ctrlstm As NetworkStream
    Private data As TcpClient
    Private datastm As NetworkStream

    Private Shared Sub Send(ByVal stm As NetworkStream, ByVal line As String)
        Dim b As Byte() = Encoding.Default.GetBytes(line)
        stm.Write(b, 0, b.Length)
    End Sub

    Private Shared Function Receive(ByVal stm As NetworkStream) As String
        Dim b(100000 - 1) As Byte
        Dim ix As Integer = 0
        Dim n As Integer
        While stm.DataAvailable
            n = stm.Read(b, ix, b.Length - ix)
            ix += n
        End While
        Return Encoding.Default.GetString(b, 0, ix)
    End Function

    Public Shared Function Command(ByVal stm As NetworkStream, ByVal cmd As String) As String
        Send(stm, cmd + Convert.ToChar(13) + Convert.ToChar(10))
        Thread.Sleep(50)
        Return Receive(stm)
    End Function

    Private Sub SetupData()
        Dim dataaddr As String = Command(ctrlstm, "PASV")
        Dim addrparts As String() = dataaddr.Split("()".ToCharArray)(1).Split(",".ToCharArray)
        Dim datahost As String = addrparts(0) + "." + addrparts(1) + "." + addrparts(2) + "." + addrparts(3)
        Dim dataport As Integer = Integer.Parse(addrparts(4)) * 256 + Integer.Parse(addrparts(5))
        data = New TcpClient (datahost, dataport)
        datastm = data.GetStream
    End Sub

    Public Sub New(ByVal host As String, ByVal username As String, ByVal password As String)
        ctrl = New TcpClient (host, 21)
        ctrlstm = ctrl.GetStream
        Command(ctrlstm, "USER " + username)
        Command(ctrlstm, "PASS " + password)
    End Sub

    Public Function Dir() As String
        SetupData
        Command(ctrlstm, "LIST")
        Dim res As String = Receive(datastm)
        Receive(ctrlstm)
        datastm.Close
        data.Close
        Return res
    End Function

    Public Function ShortDir() As String
        SetupData
        Command(ctrlstm, "NLST")
        Dim res As String = Receive(datastm)
        Receive(ctrlstm)
        datastm.Close
        data.Close
        Return res
    End Function

    Public Sub MkDir(ByVal dir As String)
        Command(ctrlstm, "MKD " + dir)
    End Sub

    Public Sub RmDir(ByVal dir As String)
        Command(ctrlstm, "RMD " + dir)
    End Sub

    Public Sub ChDir(ByVal dir As String)
        Command(ctrlstm, "CWD " + dir)
    End Sub

    Public Sub UpLoad(ByVal filename As String, ByVal binary As Boolean)
        If binary Then
            Command(ctrlstm, "TYPE I")
        Else
            Command(ctrlstm, "TYPE A")
        End If
        SetupData
        Command(ctrlstm, "STOR " + filename)
        Receive(ctrlstm)
        Dim f As FileStream = New FileStream (filename, FileMode.Open)
        Dim b(100000 - 1) As Byte
        Dim ix As Integer = 0
        Dim n As Integer
        While ix < f.Length
            n = f.Read(b, 0, b.Length)
            datastm.Write(b, 0, n)
            Thread.Sleep(100)
            ix += n
        End While
        f.Close
        datastm.Close
        data.Close
    End Sub

    Public Sub DownLoad(ByVal filename As String, ByVal binary As Boolean)
        If binary Then
            Command(ctrlstm, "TYPE I")
        Else
            Command(ctrlstm, "TYPE A")
        End If
        SetupData
        Command(ctrlstm, "RETR " + filename)
        Receive(ctrlstm)
        Dim f As FileStream = New FileStream (filename, FileMode.Create)
        Dim b(100000 - 1) As Byte
        Dim n As Integer
        While datastm.DataAvailable
            n = datastm.Read(b, 0, b.Length)
            f.Write(b, 0, n)
            Thread.Sleep(100)
        End While
        f.Close
        datastm.Close
        data.Close
    End Sub

    Public Sub Logout()
        Command(ctrlstm, "QUIT")
        ctrlstm.Close
        ctrl.Close
    End Sub
End Class

Class TestClass
    Public Shared Sub Main(ByVal args As String())
        Dim cli As FtpClient = New FtpClient ("localhost", "anonymous", "arne@")
        Console.WriteLine(cli.ShortDir)
        Console.WriteLine(cli.Dir)
        Directory.SetCurrentDirectory("C:\")
        cli.DownLoad("z.zip", True)
        cli.MkDir("subdir")
        cli.ChDir("subdir")
        cli.UpLoad("z.zip", True)
        cli.Logout
    End Sub
End Class
Avatar billede arne_v Ekspert
04. januar 2005 - 10:37 #3
Det er helt trivielt at processe alle filer i et dir:

        Dim fileEntries As String() = Directory.GetFiles("c:\dokumenter")
        Dim fileName As String
        For Each fileName In fileEntries
            ' gør noget med fileName
        Next fileName
Avatar billede arne_v Ekspert
04. januar 2005 - 10:37 #4
Det skulle gerne kunne sætte dig igang.
Avatar billede jens_k Nybegynder
04. januar 2005 - 10:41 #5
Jeg siger tusinde tak arne_v, jeg vil kigge på tingene iaften, så får du lige en kommentar fra mig iaften.

Men der er hvertfald noget at gå igang med, tusinde tak.

Mvh

Jens K
Avatar billede jens_k Nybegynder
04. januar 2005 - 19:29 #6
Hej Arne,

Nu har jeg kigget på det, og jeg kan sagtens få den til at uploade filer, så noget af det virker da :-)

Men når jeg skal uploade filer fra mapperne, så skal jeg bruge filnavnet. Hvordan får jeg lige det sat ind ?

Jeg gør sådan her, men det virker ikke:

Dim fileEntries As String() = Directory.GetFiles("c:\dokumenter")
Dim fileName As String
For Each fileName In fileEntries
  cli.UpLoad(fileName.filename, True)
Next fileName

Grunden til det ikke virker er pga "fileName.filename" ikke er gyldig, og ikke indeholder filnavnet, hvad skal jeg skrive for at hente filnavnet ind?

Endnu bedre, hvis jeg nu sammen med min exec fil ligger en tekstfil som hedder ftp.txt og deri f.eks skriver:

c:\dokumenter

Og derefter gerne vil have sådan at hver gang jeg åbner min exec fil, så tager den de mapper som står i min ftp.txt fil og uploader. Hvordan får jeg mit lille program til at læse fra en tekstfil ?

Hvis du kan hjælpe mig med dette "andet" spørgsmål, så smider jeg 100 point mere oveni. Det var en rigtig god hjælp med det første, tusinde tak skal du have for nu.

Mvh

Jens K
Avatar billede arne_v Ekspert
04. januar 2005 - 19:33 #7
Skal du ikke bare:


Dim fileEntries As String() = Directory.GetFiles("c:\dokumenter")
Dim fileName As String
For Each fileName In fileEntries
  cli.UpLoad(fileName, True)
Next fileName

?
Avatar billede arne_v Ekspert
04. januar 2005 - 19:34 #8
Jeg laver lige et eksempel med fil med dirs.
Avatar billede arne_v Ekspert
04. januar 2005 - 19:38 #9
Dim sr As StreamReader = New StreamReader("C:\dir.lst")
        Dim line As String
        line = sr.ReadLine
        While Not(line Is Nothing)
            Dim files() As String = Directory.GetFiles(line)
            Dim f As String
            For Each f In files
                ' process f
            Next
            line = sr.ReadLine
        End While
Avatar billede arne_v Ekspert
04. januar 2005 - 19:38 #10
og et svar
Avatar billede jens_k Nybegynder
04. januar 2005 - 19:48 #11
Det virker ikke med:

Dim fileEntries As String() = Directory.GetFiles("c:\dokumenter")
Dim fileName As String
For Each fileName In fileEntries
  cli.UpLoad(fileName, True)
Next fileName


Der kommer ingen fejl, men den uploader ikke noget.

Kan det være hvis stien ikke passer til den lokale fil ? For hvis man skriver:

cli.UpLoad("c:\test.txt", True)

Og selve exe filen ligger i c:\test\test.exe så kommer der ingen fejl, men filen bliver ikke uploadet. Filen skal ligge i samme dir som selve exe filen for at blive uploadet.

Mvh

Jens K
Avatar billede arne_v Ekspert
04. januar 2005 - 19:55 #12
Ups ja.

Upload tager kun et rent filnavn - ikke en fuld sti.
Avatar billede jens_k Nybegynder
04. januar 2005 - 19:57 #13
Og hvordan fikser man så lige det?

Mvh

Jens_K
Avatar billede arne_v Ekspert
04. januar 2005 - 19:57 #14
Public Sub UpLoad(ByVal filename As String, ByVal binary As Boolean)
        If binary Then
            Command(ctrlstm, "TYPE I")
        Else
            Command(ctrlstm, "TYPE A")
        End If
        SetupData
        Command(ctrlstm, "STOR " + Path.GetFileName(filename)) ' <----
        Receive(ctrlstm)
        Dim f As FileStream = New FileStream (filename, FileMode.Open)
        Dim b(100000 - 1) As Byte
        Dim ix As Integer = 0
        Dim n As Integer
        While ix < f.Length
            n = f.Read(b, 0, b.Length)
            datastm.Write(b, 0, n)
            Thread.Sleep(100)
            ix += n
        End While
        f.Close
        datastm.Close
        data.Close
    End Sub

    Public Sub DownLoad(ByVal filename As String, ByVal binary As Boolean)
        If binary Then
            Command(ctrlstm, "TYPE I")
        Else
            Command(ctrlstm, "TYPE A")
        End If
        SetupData
        Command(ctrlstm, "RETR " + Path.GetFileName(filename)) ' <----
        Receive(ctrlstm)
        Dim f As FileStream = New FileStream (filename, FileMode.Create)
        Dim b(100000 - 1) As Byte
        Dim n As Integer
        While datastm.DataAvailable
            n = datastm.Read(b, 0, b.Length)
            f.Write(b, 0, n)
            Thread.Sleep(100)
        End While
        f.Close
        datastm.Close
        data.Close
    End Sub
Avatar billede arne_v Ekspert
04. januar 2005 - 19:58 #15
Så smider den dir delen af filnavnet væk på server siden (fordi der ChDir'er man
til det dir hvor filerne skal ligges).
Avatar billede jens_k Nybegynder
04. januar 2005 - 20:09 #16
Ja, nu virker det..

Du skal have tusinde tak, nu vil jeg prøve at lege lidt videre med det.

Jeg kan dog se at hvis jeg prøver på at uploade store filer, så går det ikke for tjept selvom FTPen ligger lokalt på maskinen.

Kan man uploade på en anden måde, hvor det går hurtigere?

Og lige et slut spørgsmål, hvordan laver jeg sådan at koden automatisk kører når programmet starter? Nu ligger det på en knap man skal trykke på, det var ikke meningen.

og kan jeg lave sådan at programmet selv lukker når det er færdigt?

Mvh

Jens K
Avatar billede arne_v Ekspert
04. januar 2005 - 20:15 #17
Du kan jo prøve at lege lidt med buffer størrelse og se om det giver noget.

----

Skal du så ikke bare lave en simpel console app med koden i Main ?

Den starter og programmet slutter.
Avatar billede jens_k Nybegynder
04. januar 2005 - 23:55 #18
Jo, og hvordan laver jeg en console app ?
Avatar billede arne_v Ekspert
05. januar 2005 - 08:16 #19
Lader være med at lave en GUI app.

:-)

Du laver bare ingen Form.

For et eksempel se min  kode 04/01-2005 10:35:30 nedrst (TestClass).

Hvis du bruger Visual STudio eller SharpDevelop eller lignende så er
der formentlig ein wizard til at starte en ny console app med.
Avatar billede jens_k Nybegynder
05. januar 2005 - 13:05 #20
Yeps, det virker..

Det er bare super..

Endnu engang mange tak arne_v

Mvh

Jens K
Avatar billede jens_k Nybegynder
06. januar 2005 - 14:52 #21
Lige et Ja/Nej spørgsmål. (Hvis svaret er Ja laver jeg et nyt spørgsmål)

Er det muligt at lave differantial backup? Altså tjekke om filerne er ændret..

Mvh

Jens_K
Avatar billede arne_v Ekspert
06. januar 2005 - 15:00 #22
Ja.

Men det er lidt besværligt at parse tid på de remote filer.
Avatar billede jens_k Nybegynder
06. januar 2005 - 17:12 #23
Men svaret er ja, jeg laver et nyt spørgsmål senere, håber du er klar på at hjælpe :-)
Avatar billede arne_v Ekspert
06. januar 2005 - 19:23 #24
Ja.

Jeg har tidligere bøvlet lidt med det.
Avatar billede jens_k Nybegynder
07. januar 2005 - 10:41 #25
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester