这段代码是将文件内容读入Perl变量的好方法吗?它有效,但我很好奇我是否应该使用更好的练习.
open INPUT, "input.txt";
undef $/;
$content = <INPUT>;
close INPUT;
$/ = "\n";
Run Code Online (Sandbox Code Playgroud) 我有一个定期写入本地磁盘文件的Delphi应用程序.有时它无法访问该文件 - 尝试打开时会导致共享冲突.短暂延迟后重试就是所需要的,但是当它发生时,我想报告阻止访问的进程.
当我的程序发生共享冲突以枚举正在使用的所有文件句柄时,是否可行,检查文件名,如果它与我的数据文件的名称匹配,则检索与该句柄关联的进程名称?
一些示例代码会很好.
Perl有一个名为像文件句柄字符串被带到特征是一个文件句柄:
# let this be some nice class I wrote
package Input {
sub awesome { ... }
}
Run Code Online (Sandbox Code Playgroud)
因此,当我们做Input->awesome或非常小心:'Input'->awesome,该方法将被调用.除非:
# now somewhere far, far away, in package main, somebody does this:
open Input, "<&", \*STDIN or die $!; # normally we'd open to a file
Run Code Online (Sandbox Code Playgroud)
甚至不必执行此代码,但只有解析器才能看到此代码,以便Perl 'Input'从现在开始将字符串解释为文件句柄.因此,方法调用'Input'->awesome将会死亡,因为表示文件句柄的对象没有很棒的方法.
由于我只控制着我的班级而不是其他代码,我不能简单地决定只在每个地方使用词法文件句柄.
有什么方法可以强制我Input->awesome永远是一个方法调用Input包,但从来没有文件句柄(至少在我控制的范围内)?我认为不应该有任何名称冲突,因为Input包实际上是%Input::藏匿.
完整代码重现问题(另请参阅此ideone):
use strict;
use warnings;
use feature 'say';
say "This is …Run Code Online (Sandbox Code Playgroud) 给你一个IO::File对象或一个typeglob(\*STDOUT或Symbol::symbol_to_ref("main::FH")); 您将如何确定它是读取还是写入句柄?无法扩展接口以传递此信息(我将覆盖在实际关闭之前和之前close添加调用).flushsync
目前我正在尝试flush和sync文件句柄并忽略错误"Invalid argument"(这是我尝试flush或sync读取文件句柄时得到的):
eval { $fh->flush; 1 } or do {
#this seems to exclude flushes on read handles
unless ($! =~ /Invalid argument/) {
croak "could not flush $fh: $!";
}
};
eval { $fh->sync; 1 } or do {
#this seems to exclude syncs on read handles
unless ($! =~ /Invalid argument/) {
croak "could not sync …Run Code Online (Sandbox Code Playgroud) 我打开了一个文件来逐行阅读:
open(FH,"<","$myfile") or die "could not open $myfile: $!";
while (<FH>)
{
# ...do something
}
Run Code Online (Sandbox Code Playgroud)
稍后在程序中,我尝试重新读取文件(再次通过文件):
while (<FH>)
{
# ...do something
}
Run Code Online (Sandbox Code Playgroud)
并意识到它好像文件中的控件是在EOF并且不会从文件中的第一行迭代....这是默认行为吗?如何解决这个问题?文件很大,我不想将内存保存为数组.那么我唯一的选择是再次关闭并打开文件吗?
在Perl 5中,我可以创建一个字符串的文件句柄,并从字符串中读取或写入,就好像它是一个文件一样.这非常适合使用测试或模板.
例如:
use v5.10; use strict; use warnings;
my $text = "A\nB\nC\n";
open(my $fh, '<', \$text);
while(my $line = readline($fh)){
print $line;
}
Run Code Online (Sandbox Code Playgroud)
我怎么能在Perl 6中做到这一点?以下不为Perl 6的工作(至少对于上运行我的Perl6的实例MoarVM 2015.01从Rakudo星2015年1月发布 64位的CentOS 6.5):
# Warning: This code does not work
use v6;
my $text = "A\nB\nC\n";
my $fh = $text;
while (my $line = $fh.get ) {
$line.say;
}
# Warning: Example of nonfunctional code
Run Code Online (Sandbox Code Playgroud)
我收到错误消息:
No such method 'get' for invocant of type 'Str'
in block <unit> …Run Code Online (Sandbox Code Playgroud) 有时使用ipython时,您可能会在以写入模式打开文件的函数中遇到异常.这意味着下次运行该函数时会出现值错误,
ValueError:文件'filename'已经打开.请在写入模式下重新打开之前关闭它.
但是,由于函数被淘汰,文件句柄(在函数内部创建)将丢失,因此无法关闭.绕过它的唯一方法似乎是关闭ipython会话,此时你会收到消息:
关闭剩余的打开文件:filename ... done
有没有办法指示ipython关闭文件而不退出会话?
当我阅读Programming Perl,第2版,第51页时,有些东西让我困惑:
sub newopen {
my $path = shift;
local *FH; #not my!
open (FH, $path) || return undef;
return *FH;
}
$fh = newopen('/etc/passwd');
Run Code Online (Sandbox Code Playgroud)
我知道,为什么我们不会重新开始使用我的?到目前为止,如果我们使用my(),我看不出任何问题.
谢谢!
我在服务器上,我只限于PHP 5.2.6,这意味着我无法使用str_getcsv.我正在使用,而不是fgetcsv,它需要"一个有效的文件指针,指向由fopen(),popen()或fsockopen()成功打开的文件." 操作.
我的问题是:有没有办法将字符串作为文件句柄访问?
我的另一个选择是将字符串写入文本文件然后通过fopen()然后使用来访问它fgetcsv,但我希望有一种方法可以直接执行此操作,例如在perl中.
我有一些我称之为的子程序myWrite($fileName, \@data). myWrite()打开文件并以某种方式写出数据.我想修改,myWrite以便我可以像上面那样调用它或者使用文件句柄作为第一个参数.(这种修改的主要原因是将文件的开头委托给调用脚本而不是模块.如果有一个更好的解决方案来告诉IO子程序在哪里写,我很高兴听到它. )
为了做到这一点,我必须测试第一个输入var是否是文件句柄.我通过阅读这个问题想出了如何做到这一点.
现在这是我的问题:我还想测试是否可以写入此文件句柄.我无法弄清楚如何做到这一点.
这就是我想要做的事情:
sub myWrite {
my ($writeTo, $data) = @_;
my $fh;
if (isFilehandle($writeTo)) { # i can do this
die "you're an immoral person\n"
unless (canWriteTo($writeTo)); # but how do I do this?
$fh = $writeTo;
} else {
open $fh, ">", $writeTo;
}
...
}
Run Code Online (Sandbox Code Playgroud)
我需要知道的是,如果我可以写入文件句柄,虽然看到一些通用解决方案可以告诉您是否使用">>"或"<"打开文件句柄,或者如果不是开放等
(请注意,这个问题是相关的,但似乎没有回答我的问题.)