BufferedReader不读取文件

时间:2017-06-15 14:08:18

标签: java android bufferedreader filereader java-io

我正在尝试阅读Android 6中的/proc/net/xt_qtaguid/stats 使用cat命令,我得到了这个:

2 a0 0 0 123456 311 48329 737 48 1
3 b0 0 0 0 0 0 0 0
4 c0 123456 311 48329 737 48 1
5 d0 111111 111 22222 222 33 1

我的java代码尝试逐行读取文件:

File sysDataFile = new File(PATH_TO_FILE);
BufferedReader bufReader = null;
FileReader fileReader = null;
try {
   fileReader = new FileReader(sysDataFile);
   bufReader = new BufferedReader(fileReader);

   String line = null;
   while ((line = bufferedReader.readLine()) != null) {
       // print to console each line
       System.out.println("Line: " + line);
   }
 } catch (IOException e) {
    System.out.println("IOException thrown!");           
 } finally {
   bufReader.close();
   fileReader.close();
 }

当我运行上面的代码时,它只打印出控制台中的前两行:

Line: 2 a0 0 0 123456 311 48329 737 48 1
Line: 3 b0 0 0 0 0 0 0 0

为什么?

3 个答案:

答案 0 :(得分:13)

  

我正在尝试阅读Android 6中的/proc/net/xt_qtaguid/stats

在Linux中,/proc/下的文件实际上不是文件:它们由procfs处理,ls -l是一个特殊的文件系统,每次读取或写入文件条目时执行代码 (代码是内核模块中定义的回调函数)。因此,这些伪文件不像常规文件那样是静态的,而是完全动态。大小提供了一个有趣的线索:(大部分)这些文件的长度为0 (如cat所示),但在阅读时会显示一些内容。

简而言之,可以预期从2个不同的上下文中读取同一个文件会产生2种不同的结果。

在这种情况下,"文件"回调由xt_qtaguid module for Android处理,管理"每个应用程序/委托数据使用监控"。

This answer说:

  

这个虚拟文件的read_proc函数限制了uid,每个应用程序只能读取标题和它自己的行。

第一部分有点模糊,但似乎表明差异是基于用户ID,而模块只会" print"常规应用程序读取此文件时的2行数据(请注意Android assigns a unique user ID to each application and runs it as that user in a separate process)。

您没有提供足够的详细信息,但我必须假设当您使用TrafficStats.setThreadStatsUid()从adb打印时,您可能没有与尝试时相同的用户ID和权限从您的应用程序中读取它。我没有跟踪确切的实现细节(如果你想,the source for this module can be read here),但其他变量可能会发挥作用。

The doc says

  

对于提供网络数据传输作为服务的应用程序(例如下载管理器,媒体流服务等),可以使用以下内容将网络数据传输的所有权归属于请求应用程序的UID。 android.permission.MODIFY_NETWORK_ACCOUNTING函数调用。呼叫者必须拥有TrafficStats.setThreadStatsUid()权限才能重新分配网络流量的所有权。

因此,流程/应用程序可以使用MODIFY_NETWORK_ACCOUNTING来获取该文件中的更多行,但这需要+ '1'权限。

答案 1 :(得分:2)

由于性能不是问题,最简单和最安全的选择是在java中将cat标准输出重定向到流中并在读取器中读取内容。以此为指导:Run cat command in Android

无需修改权限以提供反引号

答案 2 :(得分:-4)

readLine()方法读取直到下一个'\ n'字符。假设,如果你有两个连续的'\ n'字符,那么readLine()可以过早地返回null。但是,如果是这种情况,那么cat应该在这两行之间增加一条线。

此时你可以尝试两件事:

  1. 检查charset你的系统文件和你的程序使用是否相同
  2. 改变这个:

    String line = null;
    while ((line = bufferedReader.readLine()) != null) {
        // print to console each line
        System.out.println("Line: " + line);
    }
    

    到此:

    char c = null;
    while ((c = (char)bufferedReader.read()) != null) {
        // print to console each char
        System.out.println("Line: " + c);
    }
    
  3. 看看会发生什么。