Filehandle STDOUT仅作为FILE重新打开输入

时间:2017-03-16 13:25:25

标签: perl

给出以下(中世纪年龄)代码:

// Your mesh data from the point cloud scan of a room
long[] indices = ...;
Vector3[] positions = = ...;

// Split your mesh data into two parts:
// one that have 60000 vertices and another that have 40000 vertices.

// create meshes
{
    Mesh mesh = new Mesh();
    GameObject obj = new GameObject();
    obj.AddComponent<MeshFilter>().sharedMesh = mesh;
    var positions = new Vector3[60000];
    var indices = new int[count_of_indices];//The value of count_of_indices depends on how you split the mesh data.

    // copy first 60000 vertices to positions and indices

    mesh.vertices = positions;
    mesh.triangles = indices;
}
{
    Mesh mesh = new Mesh();
    GameObject obj = new GameObject();
    obj.AddComponent<MeshFilter>().sharedMesh = mesh;
    var positions = new Vector3[4000];
    var indices = new int[count_of_indices];

    // copy the remaining 40000 vertices to positions and indices

    mesh.vertices = positions;
    mesh.triangles = indices;
}

我在第一个# Method to save and close the Standard output(STDOUT) and after to redirect the # STDOUT in the log file of the step sub doSomething{ open(_OLDOUT, ">&STDOUT") or Error('001', "open", "Standard OUT", __PACKAGE__, $ERRNO); close(STDOUT) or Error('001', "close", "Standard OUT", __PACKAGE__, $ERRNO); open(STDOUT, ">".$self->{logFile}) or Error('001', "open", "Standard OUT", __PACKAGE__, $ERRNO); } 命令时收到错误。错误的格式为函数open,它给出了这条消息:

Error

在此错误之前,我收到警告:

ERROR-001: System command <open> failed in file Standard OUT for module core::AnotherModule. Reason: !

这是生成它的代码行(来自FirstModule.pm):

Filehandle STDOUT reopened as FILE only for input at d:\Path/FirstModule.pm

当然这只是其背后的一大块代码。 我在互联网上搜索,乍一看似乎open FILE, "<".$file or Error('005',$file,__PACKAGE__,$ERRNO); 早先关闭,当我创建文件句柄时,它被视为STDOUT。我有什么选择?手动打开STDOUT以避免错误是否安全? 附:整个程序也是多线程的。

1 个答案:

答案 0 :(得分:6)

在Perl程序启动时,文件描述符0为STDIN,并打开输入。并打开文件描述符1和2(STDOUTSTDERR)以进行输出。关闭这些标准文件句柄是完全合法的(偶尔也有一些合理的理由)。

当您打开一个新的文件句柄时,Perl可能会使用新的文件描述符,或者它可能会重用之前已关闭的旧文件描述符。如果你关闭了一个标准的文件句柄,并且有很多很好的理由可以解释为什么你可能会这样做,Perl可能会为新的文件句柄重用标准文件描述符。

Perl在打开文件句柄并分配标准文件描述符时执行的一项检查是使用该文件描述符的预期模式检查文件句柄的模式,并在模式不匹配时发出警告。这是为了防止您使用可能难以进一步调试下游的标准文件句柄来做一些愚蠢的事情

$ perl -Mdiagnostics -we 'close STDIN;open STDIN,">foo"'
Filehandle STDIN reopened as FOO only for output at -e line 1 (#2)
    (W io) You opened for writing a filehandle that got the same filehandle id
    as STDIN.  This occurred because you closed STDIN previously.

但在合法正确地做其他事情时也会发出警告

$ perl -Mdiagnostics -we '
my $input = <STDIN>;
close STDIN;
open my $fh, ">foo";
print $fh "your input was $input";
close $fh'
Filehandle STDIN reopened as $fh only for output at -e line 4 (#1)
    (W io) You opened for writing a filehandle that got the same filehandle id
    as STDIN.  This occurred because you closed STDIN previously.

这只是一个警告。

要禁止它,您可以在关闭它们时将标准文件句柄重定向到/dev/null(或在Windows上,重定向到nul)。也就是说,而不是

close STDIN;
...
open FOO, '>foo';         # might get reassigned to fd 0

close STDIN;
open STDIN, '<nul';       # /dev/null on POSIX systems
...
open FOO, '>foo';         # won't get reassigned to fd 0
...