Verzeichnisbaum ohne Dateien auslesen
Verzeichnisbaum ohne Dateien auslesen
am 12.01.2007 10:37:24 von idontlikespam
Hallo NG,
für eine Archivierungsfunktion möchte ich den Verzeichnisbaum eines
Netzlaufwerkes in der Breite auslesen. In den Verzeichnissen liegen
teilweise mehrere hundert Dateien deren Größen zwischen wenigen kB
und bis zu 30 MB variieren. Über das Netz dauert das Stunden, wenn ich
die Verzeichnisinhalte auslese und einzeln mit "if -d" checke.
Ich habe mit Find::File=B4s preprocess probiert, komme aber da auf
keinen grünen Zweig und weiß auch nicht, ob das der richtige Ansatz
ist:
******************************* CODE ***************************
my %find_opts =3D (
preprocess =3D> \&nofile,
wanted =3D> \&do_files
);
find {preprocess =3D> \&nofile,
wanted =3D> \&do_files}, "Z:/";
sub nofile {
if($File::Find::dir ne "." && $_ ne ".." && -d $File::Find::dir) {
print "not pruned $File::Find::dir ...\n";
$File::Find::Prune =3D 1;
}
else {
print "pruned $File::Find::dir ...\n";
}
}
sub do_files {
print $File::Find::Name."\n";
}
******************************* CODE END **************************
Unter DOS klappt das ja richtig fix, wenn man "dir /AD" eingibt. Wie
macht Kleinweich das? Was wird denn da gecheckt, dass es hiermit so
schnell geht?
Hat jemand ne Idee?
Vielen Dank
Dennis
Re: Verzeichnisbaum ohne Dateien auslesen
am 12.01.2007 10:48:53 von Ingo Menger
dennis_divine schrieb:
> Ich habe mit Find::File=B4s preprocess probiert, komme aber da auf
> keinen grünen Zweig
Was immer das heißen mag.
Eine gute Idee ist, sich ein Perl Programm, das dem Gewünschten
relativ nahe kommt, folgendermaßen zu generieren:
find2perl Z:/ -type d -print
(erzeuge perl script für folgende Aufgabe: Finde in Verzeichnis Z:/
alle Directorys und gib sie aus)
Das gibt dann z.B. aus:
#! /usr/local/bin/perl -w
eval 'exec /usr/local/bin/perl -S $0 ${1+"$@"}'
if 0; #$running_under_some_shell
use strict;
use File::Find ();
# Set the variable $File::Find::dont_use_nlink if you're using AFS,
# since AFS cheats.
# for the convenience of &wanted calls, including -eval statements:
use vars qw/*name *dir *prune/;
*name =3D *File::Find::name;
*dir =3D *File::Find::dir;
*prune =3D *File::Find::prune;
sub wanted;
# Traverse desired filesystems
File::Find::find({wanted =3D> \&wanted}, 'Z:/');
exit;
sub wanted {
my ($dev,$ino,$mode,$nlink,$uid,$gid);
(($dev,$ino,$mode,$nlink,$uid,$gid) =3D lstat($_)) &&
-d _ &&
print("$name\n");
}
Re: Verzeichnisbaum ohne Dateien auslesen
am 12.01.2007 11:02:27 von idontlikespam
Hi Ingo,
Ingo Menger schrieb:
>> Ich habe mit Find::File=B4s preprocess probiert, komme aber da auf
>> keinen grünen Zweig
>
> Was immer das heißen mag.
ich komme mit meinen derzeitigen Versuchen nicht zu dem Ergebnis, das
ich gerne hätte. :)
> Eine gute Idee ist, sich ein Perl Programm, das dem Gewünschten
> relativ nahe kommt, folgendermaßen zu generieren:
>
> find2perl Z:/ -type d -print
> [...]
an dieser Stelle fällt wieder auf wie wichtig die Angabe der Platform
ist, auf der man arbeitet. :-/
Sorry, ich brauche eine Lösung für ActivePerl 5.8 unter Windows.
> [...]
Vielen Dank
Dennis
Re: Verzeichnisbaum ohne Dateien auslesen
am 12.01.2007 11:03:37 von idontlikespam
ich nehm alles zurück!
danke!
dennis
dennis_divine schrieb:
> Hi Ingo,
>
> Ingo Menger schrieb:
>
> >> Ich habe mit Find::File=B4s preprocess probiert, komme aber da auf
> >> keinen grünen Zweig
> >
> > Was immer das heißen mag.
>
> ich komme mit meinen derzeitigen Versuchen nicht zu dem Ergebnis, das
> ich gerne hätte. :)
>
> > Eine gute Idee ist, sich ein Perl Programm, das dem Gewünschten
> > relativ nahe kommt, folgendermaßen zu generieren:
> >
> > find2perl Z:/ -type d -print
> > [...]
>
> an dieser Stelle fällt wieder auf wie wichtig die Angabe der Platform
> ist, auf der man arbeitet. :-/
>
> Sorry, ich brauche eine Lösung für ActivePerl 5.8 unter Windows.
>=20
> > [...]
>=20
>=20
> Vielen Dank
> Dennis
Re: Verzeichnisbaum ohne Dateien auslesen
am 12.01.2007 11:16:32 von idontlikespam
hallo ingo,
also doch nochmal ich:
leider bringt mir nicht viel, da hier auch File::Find jeden Eintrag
einzeln darauf checkt, ob es ein Verzeichnis ist. Ergo geht das genauso
lange, als wenn ich das zu Fuß erledigt hätte.
Any other ideas?
Ingo Menger schrieb:
> dennis_divine schrieb:
>
>
> > Ich habe mit Find::File=B4s preprocess probiert, komme aber da auf
> > keinen grünen Zweig
>
> Was immer das heißen mag.
> Eine gute Idee ist, sich ein Perl Programm, das dem Gewünschten
> relativ nahe kommt, folgendermaßen zu generieren:
>
> find2perl Z:/ -type d -print
> (erzeuge perl script für folgende Aufgabe: Finde in Verzeichnis Z:/
> alle Directorys und gib sie aus)
>
> Das gibt dann z.B. aus:
>
> #! /usr/local/bin/perl -w
> eval 'exec /usr/local/bin/perl -S $0 ${1+"$@"}'
> if 0; #$running_under_some_shell
>
> use strict;
> use File::Find ();
>
> # Set the variable $File::Find::dont_use_nlink if you're using AFS,
> # since AFS cheats.
>
> # for the convenience of &wanted calls, including -eval statements:
> use vars qw/*name *dir *prune/;
> *name =3D *File::Find::name;
> *dir =3D *File::Find::dir;
> *prune =3D *File::Find::prune;
>
> sub wanted;
>
>
>
> # Traverse desired filesystems
> File::Find::find({wanted =3D> \&wanted}, 'Z:/');
> exit;
>
>
> sub wanted {
> my ($dev,$ino,$mode,$nlink,$uid,$gid);
>
> (($dev,$ino,$mode,$nlink,$uid,$gid) =3D lstat($_)) &&
> -d _ &&
> print("$name\n");
> }
Re: Verzeichnisbaum ohne Dateien auslesen
am 12.01.2007 16:45:15 von Ingo Menger
dennis_divine schrieb:
> hallo ingo,
>
> also doch nochmal ich:
>
> leider bringt mir nicht viel, da hier auch File::Find jeden Eintrag
> einzeln darauf checkt, ob es ein Verzeichnis ist. Ergo geht das genauso
> lange, als wenn ich das zu Fuß erledigt hätte.
Richtig. Das ist nun mal so. Kleiner Trost: beim 2. Mal sollte es
schneller gehen.
> Any other ideas?
a) ruf das Programm auf, das so schnell geht und lies seine Ausgabe,
ie.
open LISTING "dir /WASWEISICH |" or die "Can't do dir $!" #
ungetestet
b) frage einen Windows-Experten, wie das API heißt, was das so schnell
kann und
b.1) schau, ob ActivePerl das schon kann oder ein entsprechendes
CPAN-Module existiert
b.2) schreib ein XS Programm, das dieses API aufruft und verwende das
in Perl.
Alle 3 Möglichkeiten sind natürlich unportabel. File::Find ist evtl.
langsamer, aber 100% portabel.
Im übrigen, wenn ich mit der Explorer-Suchfunktin die Platte abgrase,
dauert das auch seine Zeit, schon gar eine Netzwerkpartition. Hast Du
zufällig immer erst Dein Programm laufen lassen und dann dir /DA?
Probier es mal andersrum.
Re: Verzeichnisbaum ohne Dateien auslesen
am 12.01.2007 17:04:39 von Wolf Behrenhoff
Ingo Menger schrieb:
> b) frage einen Windows-Experten, wie das API heißt, was das so schnell
> kann und
> b.1) schau, ob ActivePerl das schon kann oder ein entsprechendes
> CPAN-Module existiert
> b.2) schreib ein XS Programm, das dieses API aufruft und verwende das
> in Perl.
Bin zwar kein großer Experte der Win-API, aber es gibt die Funktion
FindFirstFileEx, der man einen Filter namens
FindExSearchLimitToDirectories übergeben kann. Es hängt allerdings vom
Dateisystem ab, ob dieses Filter-Flag unterstützt wird.
Wolf