2009-07-03 6 views
0

OK, donc c'est si simple mais pour la vie de moi je ne peux pas comprendre pourquoi le code ci-dessous ne fonctionne pas. J'essaie d'écrire simplement un script CGI qui crée des fichiers numérotés séquentiellement. J'utilise un compteur (stocké dans un fichier séparé) pour suivre le dernier ordinal utilisé, puis générer un nom de fichier unique en utilisant sprintf. Le fichier à nom unique n'est PAS créé. Je suppose que c'est un problème avec sprintf(...) ne pas convertir correctement $ ordinale en scalaire?Perl - pourquoi ce simple fichier open request ne fonctionnera-t-il pas?

Si je cède $ordinal par exemple en remplaçant la ligne $ordinal = <NUMPHOTOS>; avec $ordinal=42; le code fonctionne très bien et un fichier nommé 00000042.jpg est créé.

Qu'est-ce que je fais mal ici?

Aide!

my ($filename, $ordinal); 

local $| = 1; 
print "Content-type: text/plain\n\n"; 

# NOTE: $ordinal is set to zero if the file doesn't exist 
open (NUMPHOTOS, "<numpics.dat"); 
$ordinal = <NUMPHOTOS>; 
print "ordinal = $ordinal"; 
$filename = sprintf("%08d.jpg", $ordinal); 
close (NUMPHOTOS); 

open (NUMPHOTOS, ">numpics.dat"); 
$ordinal += 1; 
print NUMPHOTOS $ordinal; 
close (NUMPHOTOS); 

open (UPLOADFILE, ">$filename") or die "ERROR: can't open $filename: $! \n"; 
print "writing out file $filename...\n"; 
print UPLOADFILE 'hello world'; 
close UPLOADFILE; 
+1

Insérez print "Opening $ filename \ n"; avant la commande open (UPLOADFILE ...) pour vérifier le nom de fichier $. –

+0

Voir http://perldoc.perl.org/perlfaq5.html#I-still-don%27t-get-locking.--I-juste-pour-incrémenter-le-numéro-dans-le-fichier. --How-can-I-do-this% 3f –

Répondre

1

Perl ont pas de problème sprintf() une chaîne numéro --- il n'est pas fortement typé.

Assurez-vous d'avoir la permission de créer des fichiers avec CGI. Certains hébergeurs exigent chmod 755 sur le répertoire que vous écrivez.

+0

Une bonne idée pourrait être d'ajouter une vérification d'erreur (vérifiez toujours les erreurs sur les commandes système comme open()) sur l'appel ouvert pour le fichier NUMPHOTOS lorsque vous écrivez dessus. aussi: quel est le message d'erreur quand le fichier n'est pas créé et quel est le nom de fichier qui est généré? –

+1

en ajoutant 'use strict;' et "utiliser des avertissements"; script pourrait également vous donner des indices sur ce qui ne va pas. –

3

Commencez par ajouter "use strict, utilise les avertissements, utilise les diagnostics, use Fatal qw /: void open close /;" au début de votre code, après # !.

my $ordinal=0; 
if (-e 'numpics.dat') { 
open (my $NUMPHOTOS, "<","numpics.dat"); 
$ordinal = <$NUMPHOTOS>; 
close ($NUMPHOTOS); 
} 
print "ordinal = $ordinal\n"; 
my $filename = sprintf("%08d.jpg", $ordinal); 

De même, c'est une bonne idée de lire Ovid's CGI Course.

1

Comme tout le monde dit, vous devez:

Utilisez rétrécissements -

use strict; 
use warnings; 
use diagnostics; # will help you understand the error messages 

Vérifiez le nom du fichier, le répertoire en cours et les autorisations sur l'écriture du nom de fichier;

Utilisez le 3 ouvert paramètres et descripteurs de fichiers lexicales, et vérifier les opérations -

open my $uploadfile, '>', $filename or die "could not open $filename: $!"; 
print $uploadfile "Hello, uploadfile!\n" or die "could not print at $filename: $!"; 
close $uploadfile or die "could not close $filename: $!"; 
0
  1. Est-print "ordinal = ordinal $"; print "ordinal = 42"?
  2. Quel numéro est stocké dans numpics.dat après une exécution?
  3. Est-il possible que le script écrit 00000000.jpg encore et encore?
0

Y at-il une nouvelle ligne dans le fichier? Qu'advient-il ordinal $ si vous changez:

$ordinal = <NUMPHOTOS>; 

à

<NUMPHOTOS> =~ /(\d+)/ and $ordinal = $1; 

?

0

Voici ma tentative de réparer votre programme.

Je pense que votre problème était l'absence de chomp();

use strict; 
use warnings; 
use autodie; # don't need to check the return value of open() or close() 

my($filename, $ordinal); 

local $| = 1; 
print "Content-type: text/plain\n\n"; 

# NOTE: $ordinal is set to zero if the file doesn't exist 
{ 
    open(my $num_photos, '<', 'numpics.dat'); 
    $ordinal = <$num_photos>; 
    chomp $ordinal; # <-- 

    print "ordinal = $ordinal\n"; 
    $filename = sprintf("%08d.jpg", $ordinal); 
    print "filename = $filename\n"; 
    close ($num_photos); 
} 
{ 
    open(my $num_photos, '>', 'numpics.dat'); 
    $ordinal += 1; 
    print {$num_photos} $ordinal; 
    close($num_photos); 
} 
{ 
    open(my $upload_file, '>', $filename); 
    print "writing out file $filename...\n"; 
    print {$upload_file} 'hello world'; 
    close $upload_file; 
} 

Notez que cela ne tente toujours pas de résoudre les problèmes de verrouillage. Donc, si cela doit être atomique, vous pouvez vouloir poser une autre question

+0

Voir 'perldoc -q" Je n'ai toujours pas de verrouillage. "' Http://perldoc.perl.org/perlfaq5.html#I-still-don%27t-get-locking.--I-just-want -to-increment-the-number-in-the-file .-- Comment-peut-je-faire-ce% 3f –

+0

Ce n'était pas le problème, le problème était l'absence de 'chomp()'. –

Questions connexes