1

我试图弄清楚如何使用 SAS 命名管道在 SAS 进程中交换数据。这是一个简单的例子:

服务器

FILENAME stdout namepipe '\\.\pipe\Sas\PipeOut' server eofconnect retry=15 block;
FILENAME DIRLIST pipe 'dir "C:\atemp"';
data dirlist ;
    length buffer $256;
    infile dirlist length=reclen;
    input buffer $varying256. reclen;
    *file stdout;
    *put buffer;
ods listing file=stdout;
proc print data=dirlist;
run;

客户

FILENAME stdin  namepipe '\\.\pipe\Sas\PipeOut'  client eofconnect retry=15 block;
data d1;
    length buffer $ 256;
    infile stdin length=reclen;
    input buffer $varying256. reclen;
    put buffer;
run;

如果在服务器代码中我取​​消注释文件并放置语句并删除 ods 和 proc 打印,那么一切都按预期工作。现有的代码会产生我没想到的结果。我运行服务器代码,然后启动客户端代码。客户端代码运行但读取零观察值,如果我然后重新运行客户端代码(在服务器超时之前),它将读取 60 左右的预期行,然后挂起(永不终止)。我最好的猜测是 ods 列表语句关闭文件,然后重新打开它(并且从不关闭它?)。有谁知道发生了什么以及如何在第一次执行时在客户端中获取 ods 输出,而不会挂起?

我想做的其他事情是将服务器上的数据集输出到管道并将其用作客户端中的数据集引用。通常这是使用库引用完成的,我不知道是否或如何使管道文件引用看起来是库引用。希望最后一部分有意义。

4

1 回答 1

1

首先,要修复挂起,您需要关闭服务器上的管道。

ods listing close;

我无法解释必须运行客户端两次。

将代码更改为此有效。

服务器

FILENAME stdout namepipe '\\.\pipe\Sas\PipeOut' server eofconnect retry=15 block;
FILENAME DIRLIST pipe 'dir "C:\temp"';
data dirlist ;
    length buffer $256;
    infile dirlist length=reclen;
    input buffer $varying256. reclen;
    *file stdout;
    *put buffer;
run;

ods listing file=stdout;

proc print data=dirlist;
run;

ods listing close;

客户

FILENAME stdin  namepipe '\\.\pipe\Sas\PipeOut'  client retry=15 ;

 /*Extra read to clear whatever weirdness ODS does.*/   
data _null_;
infile stdin;
input;
run;

data d1;
    length buffer $ 256;
    infile stdin length=reclen;
    input buffer $varying256. reclen;
    put buffer;
run;

我怀疑,ODS 语句做了一些事情来创建文件。这是对管道的第一次写入。对管道的下一次写入是修改。这就是为什么你必须阅读它两次。

关于共享数据的第二个问题。我不确定您是否可以通过管道传输二进制形式的数据集。您可以将其以 CSV 之类的形式写入管道,然后将其读入客户端上的数据集中。

服务器

FILENAME stdout namepipe '\\.\pipe\Sas\PipeOut' server eofconnect retry=15 block;

proc export data=sashelp.class outfile=stdout dbms=csv replace;
run;

filename stdout clear;

在客户端上,您需要将结果写入临时文件。Proc IMPORT 需要随机访问,不能随机访问命名管道。

FILENAME stdin  namepipe '\\.\pipe\Sas\PipeOut'  client retry=15 ;

filename x temp;
data _null_;
    length buffer $4000.;
    infile stdin length=reclen;
    file x;
    input;
    buffer = _infile_;
    put buffer;
run;

proc import file=x out=class dbms=csv replace;
run;

filename x clear;
于 2013-11-03T16:45:37.367 回答