Fehler beim kopieren
am 16.01.2007 16:04:36 von guenter.moritz
Hallo an Alle,
ich schreibe gerade ein Perlprogramm mit dem ich Digi-Bilder von einer
Karte lese und auf der Festplatte speichere. Die Karte hat wohl einen
Defekt, denn es kommt zu Fehlern beim kopieren.
Mein Wunsch ist es nun im Fehlerfalle die betroffene Datei zu
protokollieren und mit der Verarbeitung fortzufahren.
Das klappt aber nicht wie die folgende Konsoleausgabe zeigt:
guenter@paris:~/Projekte/Bilderverwaltung$ perl bilderverwaltung.pl
Entry contents:
<1
<3.1
<4
<5<144canon>
<6
<5<145canon>
<6
Fehler beim Kopieren von img_4524.jpg
[...]
Fehler beim Kopieren von img_4600.jpg
<5<146canon>
pwd: konnte in â..â keine Verzeichniseintrag mit passendem Inode finden
<6<>
*** unhandled exception in callback:
*** Verzeichnis konnte nicht geöffnet werden at bilderverwaltung.pl
line 245.
*** ignoring at bilderverwaltung.pl line 117.
guenter@paris:~/Projekte/Bilderverwaltung$
Der dazu gehörende Programmabschnitt folgt :
[...]
###========================================================= =========================###
### Bilder auslesen und umbenennen
foreach $dir_zeile (sort @dir_inhalt) { ## Verzeichnis mit Bildern
print "<5<".$dir_zeile.">\n";
chdir($dir_zeile);
$work1_dir = `pwd`;
chomp($work1_dir);
print "<6<".$work1_dir.">\n";
opendir(VERZ3,$work1_dir) or die "Verzeichnis ".$work1_dir."
konnte nicht geöffnet werden";
@dir1_inhalt = readdir(VERZ3);
$erg = shift(@dir1_inhalt); ## überlesen Eintrag "."
$erg = shift(@dir1_inhalt); ## überlesen Eintrag ".."
$erg = "/bildertest";
foreach $d2 (sort @dir1_inhalt) {
@erg1 = split(/\./,$d2);
if ($erg1[1] eq "jpg") {
# print "<".$d2.">\n";
### speichern in Verzeichnis /bildertest
$erg2 = copy($d2,$erg);
if ($erg2 eq $FALSE){
print "Fehler beim Kopieren von ".$d2." \n";
}
}
}
closedir(VERZ3);
chdir("..");
}
# closedir(VERZ);
###========================================================= ==================###
[...]
Bitte nicht über den Programmierstil meckern, fange gerade mit Perl an.
Ist mein Anliegen, s.o. überhaupt so mit Perl realisierbar (Verhalten im
besagten Fehlerfall) ?
Danke für Eure Hilfe und Tipps.
Bis dann ...
MfG
Günter
Re: Fehler beim kopieren
am 16.01.2007 19:29:37 von Bernd Giegerich
Moin,
> Die Karte hat wohl einen Defekt, denn es kommt zu Fehlern
> beim kopieren.
> Mein Wunsch ist es nun im Fehlerfalle die betroffene Datei zu
> protokollieren und mit der Verarbeitung fortzufahren.
> Das klappt aber nicht wie die folgende Konsoleausgabe zeigt:
doch, klappt doch. Nur beim Verzeichniswechsel gibt er den Geist auf -
was Du ihm ja explizit auch sagst.
> opendir(VERZ3,$work1_dir) or die "Verzeichnis " [...]
Anstatt hier einen "die" zu verlangen, musst Du das ähnlich wie beim
"copy" abfangen.
> Bitte nicht über den Programmierstil meckern, fange gerade
> mit Perl an.
OK, ich versuch', konstruktiv zu bleiben... :-)
> Ist mein Anliegen, s.o. überhaupt so mit Perl realisierbar
> (Verhalten im besagten Fehlerfall) ?
ich denke schon. Wenigstens ist das, was Du im Moment kriegst, noch kein KO.
Ich fasse 'mal zusammen, was mir an Deinem Programm auffällt.
- Anstatt selbst durch die Verzeichnisse zu wandeln, könntest
Du File::Find einsetzen. Wenn Du's mehr von der "Lernen"
Seite siehst, ist's natürlich auch eine Option, das doch
selbst zu machen, um sich ein wenig mit den Datei- und
Verzeichnisfunktionen von Perl auseinander zu setzen.
- Aktuelles Verzeichnis auslesen geht eleganter mit Cwd
(Standard Modul, perldoc Cwd). Funktioniert
plattformübergreifend und ist einfacher zu kontrollieren
als ein externer Programmaufruf
- opendir(), readdir() und closedir() konsequent auf
Rückgabewerte überprüfen. Wenn Fehler toleriert
werden sollen, mit einem "if (opendir($Verzeichnis))"
Konstrukt beispielsweise.
- Aussagekräftigere Variablennamen nutzen. Mit "erg"
bis "erg2" und aehnlichem tust Du Dir keinen Gefallen.
- Die eleganteste Variante, "." und ".." zu überlesen,
wäre ein grep(). Zweiteleganteste Möglichkeit
wäre ein Check innerhalb der foreach Schleife
(z.B. mit "next if $d2 =~ /^\.{1,2}$/;").
- Den gesamten Inhalt des Verzeichnisses einzulesen
(in @dir1_inhalt) könntest Du Dir evtl. auch sparen.
"while (my $d2 = ) {" anstelle der foreach
Schleife arbeitet das ganze Eintrag für Eintrag ab.
Kann bei grossen Verzeichnissen von Vorteil sein.
Guck's Dir in Ruhe an, vielleicht hilft's ja.
Gruss,
Bernd
Re: Fehler beim kopieren
am 18.01.2007 15:37:37 von guenter.moritz
Bernd Giegerich schrieb:
Hallo Bernd,
danke für Deine Tipps. Ich werde sie mir genauer ansehen.
[...]
> > Bitte nicht über den Programmierstil meckern, fange gerade
> > mit Perl an.
>
> OK, ich versuch', konstruktiv zu bleiben... :-)
>
> > Ist mein Anliegen, s.o. überhaupt so mit Perl realisierbar
> > (Verhalten im besagten Fehlerfall) ?
>
> ich denke schon. Wenigstens ist das, was Du im Moment kriegst, noch kein
> KO.
>
> Ich fasse 'mal zusammen, was mir an Deinem Programm auffällt.
>
> - Anstatt selbst durch die Verzeichnisse zu wandeln, könntest
> Du File::Find einsetzen. Wenn Du's mehr von der "Lernen"
> Seite siehst, ist's natürlich auch eine Option, das doch
> selbst zu machen, um sich ein wenig mit den Datei- und
> Verzeichnisfunktionen von Perl auseinander zu setzen.
>
> - Aktuelles Verzeichnis auslesen geht eleganter mit Cwd
> (Standard Modul, perldoc Cwd). Funktioniert
> plattformübergreifend und ist einfacher zu kontrollieren
> als ein externer Programmaufruf
>
> - opendir(), readdir() und closedir() konsequent auf
> Rückgabewerte überprüfen. Wenn Fehler toleriert
> werden sollen, mit einem "if (opendir($Verzeichnis))"
> Konstrukt beispielsweise.
>
> - Aussagekräftigere Variablennamen nutzen. Mit "erg"
> bis "erg2" und aehnlichem tust Du Dir keinen Gefallen.
>
das schwierigste an der Programmierung ist es kurze pregnante
Variablennamen zu finden. ;-)
> - Die eleganteste Variante, "." und ".." zu überlesen,
> wäre ein grep(). Zweiteleganteste Möglichkeit
> wäre ein Check innerhalb der foreach Schleife
> (z.B. mit "next if $d2 =~ /^\.{1,2}$/;").
>
> - Den gesamten Inhalt des Verzeichnisses einzulesen
> (in @dir1_inhalt) könntest Du Dir evtl. auch sparen.
> "while (my $d2 = ) {" anstelle der foreach
> Schleife arbeitet das ganze Eintrag für Eintrag ab.
> Kann bei grossen Verzeichnissen von Vorteil sein.
>
> Guck's Dir in Ruhe an, vielleicht hilft's ja.
>
> Gruss,
> Bernd
nochmals Danke.
bis dan ...
MfG
Günter