【问题标题】:Using namedpipes to transfer ods output and datasets使用 namedpipes 传输 ods 输出和数据集
【发布时间】:2014-04-26 05:31:32
【问题描述】:

我试图弄清楚如何使用 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 输出,而不会挂起?

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

【问题讨论】:

    标签: sas named-pipes sas-ods


    【解决方案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;
    

    【讨论】:

    • 非常感谢您的回答。 ods 关闭和附加输入步骤处理了读取和挂起问题。我担心可能无法进行二进制数据集传输。我将把这个问题留几天,希望他们可能是一种方法,因为我想避免写一个文件。
    • 我将把它标记为答案。我根本不可能以这种方式传递(二进制)数据集。其他信息很准确,而且很有魅力,再次感谢
    猜你喜欢
    • 1970-01-01
    • 2020-12-07
    • 1970-01-01
    • 2021-02-06
    • 1970-01-01
    • 2017-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多