Avatar billede diyar Nybegynder
06. maj 2011 - 10:51 Der er 9 kommentarer og
1 løsning

Find last modified filer i flere på en FTP server på flere mappe

Hej

Jeg er ved at lave et program (console) i C# hvor jeg skal oprette forbindelse til en FTP server, og jeg har en sti som indeholder omkring 1000 mapper og mapperne indeholder enten 0 eller 1 eller flere filer.
F.eks.
*********************************
ftp ://folder/mappe1/
.......................mappe2/fil1.txt
.......................mappe3/testfil1.txt
.......................................testfil2.txt
.......................................testfil3.csv
*********************************
Jeg skal finde den sidst opdaterede fil i hvert mappe og gerne smede dem i en ArrayList, hvis der findes filer i mappen.
Avatar billede Syska Mester
06. maj 2011 - 13:20 #1
Okay.

Hvad er spørgsmålet ?

mvh
Avatar billede diyar Nybegynder
06. maj 2011 - 13:48 #2
Spørgsmålet er bare hvordan jeg gøre det?

Jeg har prøvet at selv lave det, men lykkedes ikke rigtigt, mit program virker kun for en mappe og ikke multiple mapper.

Mvh
Avatar billede Syska Mester
06. maj 2011 - 14:19 #3
brug List<T> og ikke ArrayList.

Hvordan ser din kode ud nu?

Hvis det virker for en mappe, så burde det vel være nemt at udvide din kode du har nu, så det kommer til at virke for flere.

mvh
Avatar billede arne_v Ekspert
07. maj 2011 - 04:24 #4
Til inspiration:

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Globalization;

namespace E
{
    public static class FTP
    {
        public class Entry
        {
            public string ParentURL { get; set; }
            public string Filename { get; set; }
            public long Size { get; set; }
            public DateTime Time { get; set; }
            public bool Directory { get; set; }
        }
        public static string ListRaw(string url)
        {
            FtpWebRequest req = (FtpWebRequest)WebRequest.Create(url);
            req.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
            using(FtpWebResponse resp = (FtpWebResponse)req.GetResponse())
            {
                using(StreamReader sr = new StreamReader(resp.GetResponseStream()))
                {
                    return sr.ReadToEnd();
                }
            }
        }
        private static string ParseLine(string line, int ix, int n)
        {
            string res = "";
            int ws = 0;
            for (int i = 1; i < line.Length; i++)
            {
                if ((line[i] == ' ') && (line[i - 1] != ' '))
                {
                    ws = ws + 1;
                }
                if ((ws >= ix) && (ws < (ix + n)))
                {
                    res = res + line[i];
                }
            }
            return res.Trim();
        }
        private static DateTime ParseTime(string s)
        {
            DateTime dt;
            if(DateTime.TryParseExact(s, "MMM d yyyy ", new CultureInfo("en-US"), DateTimeStyles.AllowWhiteSpaces, out dt))
            {
                return dt;
            }
            else if(DateTime.TryParseExact(s, "MMM d HH:mm ", new CultureInfo("en-US"), DateTimeStyles.AllowWhiteSpaces, out dt))
            {
                return dt;
            }
            else
            {
                throw new Exception("Can not parse time: " + s);
            }
        }
        private static Entry Parse(string line, string url)
        {
            string protection = ParseLine(line, 0, 1);
            long size = long.Parse(ParseLine(line, 4, 1));
            string time = ParseLine(line, 5, 3);
            string filename = ParseLine(line, 8, 100);
            return new Entry { ParentURL=url, Filename=filename, Size=size, Time=ParseTime(time), Directory=line[0]=='d' };
        }
        public static IList<Entry> List(string url)
        {
            IList<Entry> res = new List<Entry>();
            string raw = ListRaw(url);
            StringReader sr = new StringReader(raw);
            string line;
            while((line = sr.ReadLine()) != null)
            {
                if(line.Length > 40)
                {
                    res.Add(Parse(line, url));
                }
            }
            return res;
        }
        public static IList<Entry> ListRecursive(Queue<string> urls)
        {
            List<Entry> res = new List<Entry>();
            while(urls.Count > 0)
            {
                string url = urls.Dequeue();
                IList<Entry> tmp = List(url);
                foreach(Entry e in tmp)
                {
                    if(e.Directory)
                    {
                        urls.Enqueue(url + e.Filename + "/");
                    }
                }
                res.AddRange(tmp);
            }
            return res;
        }
        public static IList<Entry> ListRecursive(string url)
        {
            Queue<string> urls = new Queue<string>();
            urls.Enqueue(url);
            return ListRecursive(urls);
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine(FTP.ListRaw("ftp://ftp.dkuug.dk/pub/Xorg/"));
            foreach(FTP.Entry e in FTP.List("ftp://ftp.dkuug.dk/pub/Xorg/"))
            {
                Console.WriteLine(e.Filename + " " + e.Size + " " + e.Time + " " + e.Directory);
            }
            foreach(FTP.Entry e in FTP.ListRecursive("ftp://ftp.dkuug.dk/pub/Xorg/contrib/utilities/"))
            {
                Console.WriteLine(e.ParentURL + e.Filename + " " + e.Size + " " + e.Time + " " + e.Directory);
            }
            Console.ReadKey();
        }
    }
}
Avatar billede Pulchra Nybegynder
09. maj 2011 - 23:56 #5
Her har du en løsning som baserer sig på open source librariet ftpLib (http://ftplib.codeplex.com/).

using System;
using System.Collections.Generic;
using System.Linq;
using FtpLib;

namespace FtpTest
{
    internal class Program
    {
        private static void Main()
        {
            using (var ftp = new FtpHelper("ftpServer", "login", "password"))
            {
                List<FtpFile> ftpFiles = ftp.GetAllFiles("folder/mappe1/");
                var lastModifiedFiles =
                    from ftpFile in ftpFiles
                    group ftpFile by ftpFile.Path
                        into ftpFilesGrouped
                        select ftpFilesGrouped.OrderByDescending(file => file.Modified).First();

                foreach (var ftpFile in lastModifiedFiles)
                {
                    Console.WriteLine(string.Format("File: {0}. Modified: {1}", ftpFile.Path + ftpFile.Name, ftpFile.Modified));
                }
            }
        }
    }

    internal class FtpFile
    {
        public string Path { get; set; }
        public DateTime? Modified { get; set; }
        public string Name { get; set; }
    }

    internal class FtpHelper : IDisposable
    {
        private readonly FtpConnection _ftpConnection;

        public FtpHelper(string ftpServer, string login, string password)
        {
            _ftpConnection = new FtpConnection(ftpServer, login, password);
            _ftpConnection.Open(); /* Open the FTP connection */
            _ftpConnection.Login(); /* Login using previously provided credentials */
        }

        #region IDisposable Members

        public void Dispose()
        {
            if (_ftpConnection != null)
            {
                _ftpConnection.Close();
            }
        }

        #endregion

        public List<FtpFile> GetAllFiles(string path)
        {
            var ftpFiles = new List<FtpFile>();
            GetFiles(path, ftpFiles);
            return ftpFiles;
        }

        private void GetFiles(string path, List<FtpFile> ftpFiles)
        {
            foreach (FtpDirectoryInfo directory in _ftpConnection.GetDirectories(path))
            {
                GetFiles(path + directory.Name + "/", ftpFiles);
            }

            ftpFiles.
                AddRange(_ftpConnection.GetFiles(path).
                Select(file => new FtpFile
                {
                    Modified = file.LastWriteTime,
                    Name = file.Name,
                    Path = path
                }));
        }
    }
}

mvh
Hallur
Avatar billede diyar Nybegynder
30. maj 2011 - 11:23 #6
Til --> arne_v

Kunne man gøre det sådan, så man også på en måde angive brugernavn og password, for din kode er til en FTP server som ikke kræver authinication.

Til --> Pulchra
Når jeg kører programmet så bliver jeg bedt om at angive sti til en .cs fil.
Avatar billede arne_v Ekspert
30. maj 2011 - 14:39 #7
Syntaxen for FTP URL er:

ftp://server/path/

eller:

ftp://brugernavn:password@server/path/

sa du kan bare angive det i URL.
Avatar billede arne_v Ekspert
30. maj 2011 - 14:42 #8
Hvis du foretraekker ikke at have det i URL saa:

        public static string ListRaw(string url, string un, string pw)
        {
            FtpWebRequest req = (FtpWebRequest)WebRequest.Create(url);
            req.Credentials = new NetworkCredential(un, pw);
            req.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
            using(FtpWebResponse resp = (FtpWebResponse)req.GetResponse())
            {
                using(StreamReader sr = new StreamReader(resp.GetResponseStream()))
                {
                    return sr.ReadToEnd();
                }
            }
        }

[ret selv List og ListRecursive metoderne]
Avatar billede diyar Nybegynder
13. juni 2011 - 23:24 #9
arne_v --> Kan du skrive et svar? Så jeg kan give point.
Avatar billede arne_v Ekspert
14. juni 2011 - 00:50 #10
svar
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
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

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