Android中bufferedReader.readLine()返回null问题求助
问题排查与解决
核心原因分析
1. 输出流向标准错误流(stderr)
lighttpd启动时的日志信息并未输出到标准输出(stdout),而是发送到了标准错误流(stderr)。你当前的代码仅读取了stdout,自然返回null——而shell终端默认会同时显示stdout和stderr的内容,所以你在shell里能看到输出。
2. 子进程阻塞导致输出无法读取
如果子进程的stderr缓冲区被填满,进程会被挂起,无法继续输出内容,这也会导致你读取stdout时拿不到任何数据,最终返回null。
解决方法
方法一:同时读取stdout和stderr
启动单独线程分别处理两个流,避免缓冲区阻塞:
Process process = Runtime.getRuntime().exec("./etc/lighttpd -D -f /etc/test.conf"); // 处理标准输出 new Thread(() -> { try (BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { String line; while ((line = stdoutReader.readLine()) != null) { Log.d(TAG, "stdout: " + line); } } catch (IOException e) { e.printStackTrace(); } }).start(); // 处理标准错误 new Thread(() -> { try (BufferedReader stderrReader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) { String line; while ((line = stderrReader.readLine()) != null) { Log.d(TAG, "stderr: " + line); } } catch (IOException e) { e.printStackTrace(); } }).start(); // 等待进程结束,避免僵尸进程 try { int exitCode = process.waitFor(); Log.d(TAG, "进程退出码: " + exitCode); } catch (InterruptedException e) { e.printStackTrace(); }
方法二:将stderr重定向到stdout
通过shell命令把stderr的内容合并到stdout,这样只需读取一个流即可:
// 使用shell执行命令并添加2>&1重定向 Process process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", "./etc/lighttpd -D -f /etc/test.conf 2>&1"}); try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { String line; while ((line = bufferedReader.readLine()) != null) { Log.d(TAG, "输出: " + line); } int exitCode = process.waitFor(); Log.d(TAG, "进程退出码: " + exitCode); } catch (IOException | InterruptedException e) { e.printStackTrace(); }
补充说明
- 由于
lighttpd -D是前台运行的守护进程,会持续运行,所以需要保持读取流的线程存活,否则缓冲区满后进程会挂起。 - 务必调用
waitFor()等待进程结束,避免子进程成为僵尸进程占用系统资源。
内容的提问来源于stack exchange,提问作者GNK
相关产品推荐
相关产品推荐

