Perl - 为什么这个简单的文件打开请求不起作用?

时间:2009-07-03 07:51:15

标签: perl cgi

好的,所以这很简单,但对于我的生活,我无法弄清楚为什么下面的代码不起作用。

我正在尝试简单地编写一个CGI脚本来创建顺序编号的文件。我正在使用计数器(存储在单独的文件中)来跟踪最后使用的序号,然后使用sprintf生成唯一的文件名。未创建唯一命名的文件。我怀疑sprintf(...)没有正确地将$ ordinal转换为标量是一个问题?

如果我通过用$ordinal替换行$ordinal = <NUMPHOTOS>;来指定$ordinal=42;,则代码可以正常工作,并且会创建名为00000042.jpg的文件。

我在这里做错了什么?

帮助!

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;

6 个答案:

答案 0 :(得分:3)

首先添加“use strict;使用警告;使用诊断;使用Fatal qw /:void open close /;”在代码开始时,#!。

之后
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 );

阅读Ovid's CGI Course也是个好主意。

答案 1 :(得分:1)

Perl没有问题sprintf()一个字符串数字---它没有强类型。

确保您拥有使用CGI创建文件的权限。某些网络托管在您编写的目录中需要chmod 755

答案 2 :(得分:1)

正如大家所说,你应该:

使用限制 -

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

检查文件名,当前目录和写入文件名的权限;

使用3参数open和词法文件句柄,并检查操作 -

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: $!";

答案 3 :(得分:0)

  1. 是否打印“ordinal = $ ordinal”;打印“ordinal = 42”?
  2. 运行后在numpics.dat中存储了多少个数字?
  3. 脚本是否有可能一遍又一遍地写00000000.jpg?

答案 4 :(得分:0)

文件中是否有换行符?如果你改变,$ ordinal会发生什么:

$ordinal = <NUMPHOTOS>;

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

答案 5 :(得分:0)

以下是我尝试修复您的计划。

我认为您的问题是缺少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;
}

请注意,这仍然不会尝试解决锁定问题。所以如果这需要是原子的,你可能想问另一个问题