使用namedpipes传输ods输出和数据集

时间:2013-11-02 17:57:24

标签: sas named-pipes sas-ods

我正在试图弄清楚如何使用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 listing语句关闭文件,然后重新打开它(并且从不关闭它?)。有没有人知道发生了什么以及如何在第一次执行时获取客户端的ods输出,没有挂起?

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

1 个答案:

答案 0 :(得分: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;