使用ProcessBuilder捕获输出时InputStream为何随机为空?
问题:调用Process执行grep时前几次结果随机为空
我在Stack Overflow上查找过类似问题,但未找到有效解决方案。我的代码如下:
ResultSet rs = stmt.executeQuery(); int ret = 0; while (rs.next()) { int rsID = rs.getInt("ID"); String rsGID = rs.getString("GID"); logger.log(Level.INFO, ""); logger.log(Level.INFO, "ID / GID: {0}", rsID + " / " + rsGID); ProcessBuilder builder = new ProcessBuilder(new String[] { "bash", "-c", "grep " + rsGID + " /media/newdrive/*"}); Process proc = builder.redirectErrorStream(true).start(); //while (proc.isAlive()); String smatch = StringEscapeUtils.unescapeXml(new String(proc.getInputStream().readAllBytes(), StandardCharsets.UTF_8)).replaceAll("\R", ""); ret = proc.waitFor(); String sURL = StringUtils.substringBefore(StringUtils.substringAfter(smatch, "<loc>"), "</loc>"); String sField = StringUtils.substringAfterLast(StringUtils.substringBefore(smatch, "."), "/").replaceAll("[0-9_]", ""); logger.log(Level.INFO, "URL: {0}", rsID + " / " + sURL); logger.log(Level.INFO, "Field: {0}", rsID + " / " + sField); proc.destroy(); } rs.close();
出现的问题是前两组结果会随机为空:前两次循环输出的URL和Field字段为空,后续结果正常。
我的临时解决方法是取消注释while (proc.isAlive());并注释waitFor()后,前两组结果能正常获取。我是否误用了waitFor()?似乎很多开发者都遇到过同样问题,希望得到指导。
另外,出于性能考虑我选择使用原生grep:我们有100多个XML文件,每个约20万行,需定期匹配1000多个GID。
更新
我将代码修改为:
ByteArrayOutputStream outError = new ByteArrayOutputStream(); Process proc = builder.redirectErrorStream(false).start(); proc.getErrorStream().transferTo(outError);
但问题依旧,仍会偶尔得到空结果。经多次测试,甚至while (proc.isAlive());也失效了。
目前我在ResultSet循环前加入一段代码,用假数据启动并结束一个Process。由于空结果仅出现在首次Process执行时,现在循环内的数据获取始终稳定,已通过充分测试。
内容的提问来源于stack exchange,提问作者Rubens Amaral
相关产品推荐
相关产品推荐

