2011-03-18 38 views
10

大多數語言支持雙向過程通信。例如,在Python,我可以(拖泥帶水)做:R中的讀寫管道()通信

>>> from subprocess import * 
>>> p = Popen('nslookup', stdin=PIPE, stdout=PIPE) 
>>> p_stdin, p_stdout = p.communicate("www.google.com") 
>>> print p_stdin 
Server:  ... 

在R,我只能似乎走一條路,不管我是否打開我的菸斗「R +」或「W +」。此外,即使我通過R -f ...R < ...運行腳本,奇怪的行爲也會在實際的控制檯stdin/stdout中出現。

我的問題歸結爲以下幾點 - 是否有可能(無需編寫C方法!)在上面的Python示例R中重現雙向進程通信?

回答

4

很久以前,我還在Octave中使用雙向管道,所以,這是很好的。但仔細閱讀help(pipe)並不表明這是支持。您可以閱讀書寫,但看起來不是兩種。

但也許你可以作弊。打開一個管道寫入一個應用程序,您可以調用一個stdout重定向到一個文件...然後繼續閱讀該文件。儘管如此,由於非刷新緩衝區可能會造成混亂。

+0

這是一個與基地的平臺兼容性問題?我應該在那裏提交一個錯誤/問題? 此外,文件選項在技術上是一個解決方案,但實際上這是爲了管道大量的SQL結果以避免錯誤的ODBC驅動程序,因此寫入磁盤並重新讀入會很慢。 – mjbommar 2011-03-18 18:19:12

+0

我在Linux上試過,如果R支持它的話,它會有它。沒有必要提交錯誤報告,除非您可以編寫代碼或支付某人的費用--R Core的手已滿。最後,我個人傾向於通過......編寫直接的數據庫訪問塊來避免錯誤的ODBC驅動程序。在那裏,通過一些GSoC指導,爲彭博,Lim,OneTick以及PostgreSQL等後端做好了準備。你的後端是什麼? – 2011-03-18 18:29:31

+0

@mjbommar,我還沒有找到一種方法來做你所描述的,我花了幾個小時嘗試。但是,如果您只是試圖在不使用ODBC驅動程序的情況下將SQL數據庫結果轉換爲R,則可能不需要雙向交互。嘗試使用system()連接它並將查詢作爲輸入提供。我這樣做是爲了訪問我所有的數據庫(這需要RMySQL無法做到的SSH隧道)。 – Noah 2011-03-18 19:25:48

1

它可能像這樣從R運行Jython中的那部分。加載java(在第二條語句中出現)會很慢,但在此之後應該沒問題。

library(rJython) 

.Jython <- rJython() 

jython.assign(.Jython, "x", "www.google.com") 
jython.exec(.Jython, "from subprocess import * 
p = Popen('nslookup', stdin=PIPE, stdout=PIPE) 
p_stdin, p_stdout = p.communicate(x)") 

cat(jython.get(.Jython, "p_stdin"), "\n\n") 

最後一條語句給出:

> cat(jython.get(.Jython, "p_stdin"), "\n\n") 
Default Server: UnKnown 

Address: 192.168.0.1 



> www.google.com 
+0

我投了這個票,因爲它可能適用於某些人,但是這個選項會爲我的應用程序調用太多開銷。 – mjbommar 2011-03-20 15:23:49

+0

@mbommar,你指的是什麼開銷?如果速度慢,那麼''.jython < - rJython()'語句(就像加載JVM一樣)只需要在會話開始時執行一次,所以它隻影響啓動時間。如果啓動時間很重要,那麼我同意這會是一個問題。 – 2011-03-20 16:16:32

11

一種方式做到這一點的類UNIX系統就會打開一個管道被重定向stdoutstderr到FIFO的過程:

# Setup 
system('mkfifo output.fifo') 
p_out <- fifo('output.fifo', 'r') 
p_in <- pipe('pdflatex &> output.fifo', 'w') 

# See what TeX said on startup 
readLines(p_out) 
[1] "This is pdfTeX, Version 3.1415926-1.40.11 (TeX Live 2010)" 

readLines(p_out) 
character(0) # TeX has nothing more to say 

# Tell TeX to do something 
writeLines('\\documentclass{article}', p_in) 
flush(p_in) 

# See what it said in response 
readLines(p_out) 
[1] "**entering extended mode"              
[2] "LaTeX2e <2009/09/24>"               
[3] "Babel <v3.8l> and hyphenation patterns for english, dumylang, nohyphenation, ba" 
[4] "sque, danish, dutch, finnish, french, german, ngerman, swissgerman, hungarian, " 
[5] "italian, bokmal, nynorsk, polish, portuguese, spanish, swedish, loaded."   
[6] "" 

不幸的是,Windows不支持fifo