Groovy管道是真正的UNIX管道吗?
我今天刚开始研究Groovy。我考虑使用它来替换一些更复杂的BASH脚本。 对我来说,其中一个非常有趣的概念是:Groovy管道是真正的UNIX管道吗?,groovy,Groovy,我今天刚开始研究Groovy。我考虑使用它来替换一些更复杂的BASH脚本。 对我来说,其中一个非常有趣的概念是: 太棒了。但我的问题是:这是使用真正的UNIX管道(例如在Linux上运行时),还是只是使用Java流进行模拟?(如果是这样的话,它会慢得多/效率更低吗?由于运算符重载,它最终在Groovy运行时调用,Groovy运行时确实使用java流模拟管道: /** * Allows one Process to asynchronously pipe data to anot
太棒了。但我的问题是:这是使用真正的UNIX管道(例如在Linux上运行时),还是只是使用Java流进行模拟?(如果是这样的话,它会慢得多/效率更低吗?由于运算符重载,它最终在Groovy运行时调用,Groovy运行时确实使用java流模拟管道:
/**
* Allows one Process to asynchronously pipe data to another Process.
*
* @param left a Process instance
* @param right a Process to pipe output to
* @return the second Process to allow chaining
* @throws java.io.IOException if an IOException occurs.
* @since 1.5.2
*/
public static Process pipeTo(final Process left, final Process right) throws IOException {
new Thread(new Runnable() {
public void run() {
InputStream in = new BufferedInputStream(getIn(left));
OutputStream out = new BufferedOutputStream(getOut(right));
byte[] buf = new byte[8192];
int next;
try {
while ((next = in.read(buf)) != -1) {
out.write(buf, 0, next);
}
} catch (IOException e) {
throw new GroovyRuntimeException("exception while reading process stream", e);
} finally {
closeWithWarning(out);
}
}
}).start();
return right;
}
不过,我无法直言不讳地谈论所涉及的开销。Groovy不能使用Unix管道,因为必须在启动子进程之前设置Unix管道。但您的示例首先启动所有进程,然后用管道连接它们
Groovy还必须调用一些文件句柄操作系统调用(
dup
,dup2
),如果不使用其他本机库,这些调用在JVM中不可用。我发现Groovy管道模拟比unix管道慢得多:
Bash命令
zcat dump.sql.gz | mysql -u${mysql_user} --password=${mysql_password} -D${db_name}
大约需要40分钟
groovy也是如此
def proc1 = ["zcat", "${sqlGzFile.getPath()}"].execute()
def proc2 = ["mysql", "-u${mysqlUser}", "--password=${mysqlPassword}", "-D$dbName"].execute()
proc1 | proc2
proc2.waitFor()
大约需要2小时40分钟
但是,您可以使用以下设备制作管道:
def proc = ["sh", "-c", "zcat dump.sql.gz | mysql -u${mysql_user} --password=${mysql_password} -D${db_name}"].execute()
proc.waitFor()
我确信dup、dup2在JVM中是可用的。JVM已经进行了大量的本机文件句柄争用。如果这是你的意思,它们可能不会暴露给用户。
def proc = ["sh", "-c", "zcat dump.sql.gz | mysql -u${mysql_user} --password=${mysql_password} -D${db_name}"].execute()
proc.waitFor()