Verzeichnis auslesen nach bestimmten Kriterien

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Verzeichnis auslesen nach bestimmten Kriterien

    Hallo,
    ich möchte gern ein Verzeichnis auslesen, dabei aber am Ende nur die Dateien bekommen, die einem bestimmten Kriterium entsprechen
    Bisher habe ich folgendes:
    PHP-Code:
    if ($handle opendir("pfad")) {
      while (
    false !== ($file readdir($handle))) {
    // $pattern = "";
    //    if ( preg_match($pattern, $file) )
        
    echo $file."<br>";
      }
      
    closedir($handle);

    Nun scheitert es bei mir bei dem preg_match Pattern.
    Die Dateien haben folgende Struktur:
    jfBI8BJKD_page_0001.png
    jfBI8BJKD_page_0002.png
    jfBI8BJKD_page_0003.png
    3kGsd78J_page_0001.png
    3kGsd78J_page_0002.png
    usw
    Am ende möchte ich nur wissen wieviele "Seiten" (Bilder) jede Nummer hat.

    Muss ich da überhaupt mit preg_match rangehen oder gibt es etwas performanteres? Das Verzeichnis kann später unter Umständen >100.000 Dateien beinhalten
    Mess with the Besth, die like the rest!

  • #2
    Hallo,

    ich würde da mit einem FilterIterator über einem DirectoryIterator herangehen und dann einen Gruppenwechsel machen.

    Gruß,

    Amica
    [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
    Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
    Super, danke!
    [/COLOR]

    Kommentar


    • #3
      Zitat von Besth Beitrag anzeigen
      Das Verzeichnis kann später unter Umständen >100.000 Dateien beinhalten
      Dann kannst du Performance aber gleich auf den „ist mir nicht so wichtig“-Zettel notieren ...

      jfBI8BJKD_page_0001.png
      jfBI8BJKD_page_0002.png
      jfBI8BJKD_page_0003.png
      3kGsd78J_page_0001.png
      3kGsd78J_page_0002.png
      Da gehört m.E. anstelle des ersten Unterstriches ein Slash rein, wenn das halbwegs performant umgesetzt werden soll.
      I don't believe in rebirth. Actually, I never did in my whole lives.

      Kommentar


      • #4
        Zitat von Besth Beitrag anzeigen
        Hallo,
        ich möchte gern ein Verzeichnis auslesen, dabei aber am Ende nur die Dateien bekommen, die einem bestimmten Kriterium entsprechen
        Bisher habe ich folgendes:
        PHP-Code:
        if ($handle opendir("pfad")) {
          while (
        false !== ($file readdir($handle))) {
        // $pattern = "";
        //    if ( preg_match($pattern, $file) )
            
        echo $file."<br>";
          }
          
        closedir($handle);

        Nun scheitert es bei mir bei dem preg_match Pattern.
        Und an welcher Stelle im Pattern, wenn man fragen darf?

        Die Dateien haben folgende Struktur:
        jfBI8BJKD_page_0001.png
        jfBI8BJKD_page_0002.png
        jfBI8BJKD_page_0003.png
        3kGsd78J_page_0001.png
        3kGsd78J_page_0002.png
        usw
        Ist die Unterscheidung von Groß- und Kleinschreibung wichtig oder nicht?

        Gibts in dem Verzeichnis noch Dateien mit anderem Namensmustern? Dann wird das "Pattern" länger. Wenn nicht, reicht es, die Ziffern vor dem ".png" zu erfassen.

        Ist die Zeichenanzahl aller Namen gleich? Dann reicht substr().

        Am ende möchte ich nur wissen wieviele "Seiten" (Bilder) jede Nummer hat.
        Ach so, also eine Art Fold-Funktion für ein Verzeichnis.

        Muss ich da überhaupt mit preg_match rangehen oder gibt es etwas performanteres? Das Verzeichnis kann später unter Umständen >100.000 Dateien beinhalten
        Erstmal ist preg_match() per se nicht "unperformant". Woher kommen nur immer diese irrigen Annahmen?[0]

        Ob du preg_match() oder eine ähnliche Mustersuchfunktion[1] benötigst, hängt (wie oben schon angedeutet) von den Namensmustern ab, die vorhanden sind und welche davon du "einfangen" möchtest.

        Bei Verzeichnissen, die mehrere 100k Einträge haben, dürfte der Overhead von preg_match() nicht ins Gewicht fallen.

        Dagegen habe ich bei Tests an Verzeichnissen mit ein paar tausen Einträgen unter Windows mit NTFS festgestellt, dass die gewöhnlichen Verzeichnisfunktionen (opendir(), readdir(), ...) oder das Dir-Objekt 50 bis 100 Prozent schneller sind als die SPL-Directory-Iteratoren. Frag mich aber bitte nicht, warum[2]. Ich war selbst überrascht, dass ein Haufen PHP-Script-Code einen Haufen C so deutlich schlägt ...

        PHP-Code:
        // Der Default-Wert von $pcre ist ein Vorschlag.
        // Er lässt sich sicher noch optimieren.
        // Aber erstmal funktioniert er.

        function count_files(
            
        $url/// string() directory path
            
        $pcre '/\A(.+)[0-9]+\.png\z/'/// string(pcre) regex pattern
            
        $xmpl_basename 'jfBI8BJKD_page_0001.png' /// for testing the regex
        ) {
            if (
                !
        is_int(@preg_match($pcre$xmpl_basename$hits)) ||
                
        count($hits) < // we use $hits[1] later
            
        ) {
                return 
        null// invalid regex pattern
            
        }
            if (!
        is_resource($dir opendir($url))) {
                return 
        null// could not open directory
            
        }
            
        $pwd getcwd(); // memoize current working dir
            
        if (!chdir($url)) {
                return 
        null// could not change current working dir
            
        }
            
        $accu = array (); /// assoc array
            
        while (is_string($entry readdir())) {
                if (!
        is_file($entry)) {
                    continue; 
        // skip non-files
                
        }
                if (!
        preg_match($pcre$entry$hits)) {
                    continue; 
        // skip non-matching filenames
                
        }
                
        $base $hits[1]; // if file-system is case-sensitive
                
        if (!isset ($accu[$base])) {
                    
        $accu[$base] = 0;
                }
                
        $accu[$base] += 1;
            }
            
        closedir($dir);
            
        chdir($pwd); // switch back to previous working dir
            
        return $accu;


        [0] Die gerne zitierte Aussage im PHP-Handbuch, dass preg_match() und Kollegen nicht für "einfache" String-Suche benutzt werden sollten, ist Unsinn. Die "Performance" hängt immer vom konkreten Anwendungsfall ab.

        [1] PHP hat bspw. auch glob(), fnmatch() und einen "FilterIterator", der über Verzeichnisse operieren kann.

        [2] Vermutlich bauen die den üblichen Opendir-readdir-closedir-Ablauf auch nur als C-Version mit den Funktionen der Zend-Engine nach und packen dann den Iterator-Krempel obendrauf.

        P.S.: Man lernt eben nie aus: Ich wollte gerade einen vermeintlichen Fehler berichtigen, und readdir() durch readdir($dir) zu ersetzen, stellte aber fest, dass das Script auch ohne extra Argument funktioniert. Im Handbuch ist keine PHP-Versionsnummer erwähnt, ab der dieses Argument optional wurde. Was heißt: Das war höchstwahrscheinlich schon immer so ...
        Zuletzt geändert von fireweasel; 05.08.2011, 13:35.
        Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

        Kommentar

        Lädt...
        X