04. januar 2005 - 10:09Der 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?
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
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
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.
Dim fileEntries As String() = Directory.GetFiles("c:\dokumenter") Dim fileName As String For Each fileName In fileEntries cli.UpLoad(fileName, True) Next fileName
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
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.
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
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?
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.