android中读文件流的关闭

问题描述:
在开发imonitor工具时,遇到一个很严重的问题,在某些机型上运行实时监控时,会在打开监控后几秒钟就FC了,log显示异常为:

11-22 10:48:56.467 W/System.err(  557): java.io.IOException: Error running exec(). Command: [sh, -c, cat /sys/class/power_supply/battery/status] Working Directory: null Environment: null
11-22 10:48:56.467 D/iMonitor: CpuDataCollector(  557):  getUserUsage(): 100* ((62622 - 62482)/(2378876 - 2375017))=3
11-22 10:48:56.468 W/System.err(  557):     at java.lang.ProcessManager.exec(ProcessManager.java:211)
11-22 10:48:56.468 W/System.err(  557):     at java.lang.Runtime.exec(Runtime.java:174)
11-22 10:48:56.468 W/System.err(  557):     at java.lang.Runtime.exec(Runtime.java:129)
11-22 10:48:56.468 W/System.err(  557):     at com.sprd.tool.d.a.a(Unknown Source)
11-22 10:48:56.468 W/System.err(  557):     at com.sprd.tool.c.h.c(Unknown Source)
11-22 10:48:56.468 W/System.err(  557):     at com.sprd.tool.c.b.run(Unknown Source)
11-22 10:48:56.468 W/System.err(  557):     at java.util.Timer$TimerImpl.run(Timer.java:284)
11-22 10:48:56.468 W/System.err(  557): Caused by: java.io.IOException: Too many open files
11-22 10:48:56.469 W/System.err(  557):     at java.lang.ProcessManager.exec(Native Method)
11-22 10:48:56.469 W/System.err(  557):     at java.lang.ProcessManager.exec(ProcessManager.java:209)
11-22 10:48:56.469 W/System.err(  557):     ... 6 more

问题分析:
由于在打开监控时,会每秒大量cat读取手机中的系统参数文件,导致too many open files异常。通过 cat /proc/sys/fs/file-max可以查看系统允许打开的最大句柄数,但终归是有个极限的,随着时间推移,打开的文件数一定会达到上限而发生异常,最正确的解决方案是每读一次文件就关一个文件。

解决方案:

try {
            proc = runtime.exec(args);
            InputStream inputstream = proc.getInputStream();
            InputStreamReader inputstreamreader = new InputStreamReader(
                    inputstream);
            bufferedreader = new BufferedReader(inputstreamreader);
            // read the ls output
            String line = "";
            sb = new StringBuilder(line);
            while ((line = bufferedreader.readLine()) != null) {
                ...
            }
            if (proc.waitFor() != 0) {
                Log.d(TAG, "exit value = " + proc.exitValue());
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (bufferedreader != null) {
                try {
                    bufferedreader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

对于new BufferReader(new InputStreamReader(new InputStream(...)));这种多层次的流调用,只需对最外层执行close(),外层的会依次关闭里层的。

你可能感兴趣的:(apk应用开发)