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

发布于 2024-07-26 05:38:35 字数 1010 浏览 4 评论 0原文

好吧,这很简单,但我一生都无法弄清楚为什么下面的代码不起作用。

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

如果我通过将行 $ordinal =; 替换为 $ordinal=42; 来分配 $ordinal ,则代码可以正常工作,并且将创建一个名为 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;

OK, so this is so simple but for the life of me I can't figure out why the code below doesn't work.

I'm trying to simply write a CGI script that creates sequentially numbered files. I'm using a counter (stored in a separate file) to keep track of the last ordinal used, and then generating a unique filename using sprintf. The uniquely named file is NOT created. I suspect it's an issue with sprintf(...) not correctly converting $ordinal to a scalar?

If I assign $ordinal by say replacing the line $ordinal = <NUMPHOTOS>; with $ordinal=42; the code works fine and a file named 00000042.jpg is created.

What am I doing wrong here?

Help!

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

最笨的告白 2024-08-02 05:38:35

首先添加“use strict;use warnings;use Diagnostics;use 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 的 CGI 课程也是个好主意。

First add "use strict;use warnings;use diagnostics;use Fatal qw/:void open close/;" at start of your code, after #!.

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

Also it is a good idea to read Ovid's CGI Course.

江挽川 2024-08-02 05:38:35

Perl 对 sprintf() 字符串数字没有问题 --- 它不是强类型的。

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

Perl have no problem sprintf() a string-number --- it is not strongly typed.

Make sure you have the permission to create files with CGI. Some web hosting require chmod 755 on the directory you write.

分分钟 2024-08-02 05:38:35

正如大家提到的,你应该:

使用限制——

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

检查文件名、当前目录以及写入文件名的权限;

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

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

As everybody mentioned, you should:

Use strictures --

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

Check the file name, the current directory and the permissions on writing the filename;

Use the 3-parameter open, and lexical filehandles, AND check the operations --

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: $!";
蓝戈者 2024-08-02 05:38:35
  1. 是否打印“ordinal = $ordinal”; 打印“序数= 42”?
  2. 运行后 numpics.dat 中存储的数字是多少?
  3. 脚本有可能一遍又一遍地写入 00000000.jpg 吗?
  1. Does print "ordinal = $ordinal"; print "ordinal = 42"?
  2. What number is getting stored in numpics.dat after a run?
  3. Is it possible the script is writing 00000000.jpg over and over again?
谜泪 2024-08-02 05:38:35

文件中有换行符吗? $ordinal 会发生什么

$ordinal = <NUMPHOTOS>;

如果将:更改为

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

Is there a newline in the file? What happens to $ordinal if you change:

$ordinal = <NUMPHOTOS>;

to

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

?

再见回来 2024-08-02 05:38:35

这是我修复你的程序的尝试。

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

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

Here is my attempt to fix up your program.

I think your problem was the lack of 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;
}

Note that this still doesn't attempt to resolve locking problems. So if this needs to be atomic, you may want to ask another question

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文