BufferedReader不读取文件中的所有行

Lee*_*fin 6 java android filereader bufferedreader java-io

我试图/proc/net/xt_qtaguid/stats在Android 6中阅读.
使用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
Run Code Online (Sandbox Code Playgroud)

我的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();
 }
Run Code Online (Sandbox Code Playgroud)

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

Line: 2 a0 0 0 123456 311 48329 737 48 1
Line: 3 b0 0 0 0 0 0 0 0
Run Code Online (Sandbox Code Playgroud)

为什么?

Hug*_* M. 13

我想/proc/net/xt_qtaguid/stats在Android 6中阅读.

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

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

在这种情况下,"文件"回调由xt_qtaguidAndroid模块处理,该模块管理"每个应用程序/委托数据使用监视".

这个答案说:

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

第一部分有点模糊,但似乎表明差异是基于用户ID,并且模块只会在常规应用程序读取此文件时"打印"2行数据(请注意Android为每个应用程序分配唯一的用户ID并在单独的进程中以该用户身份运行它).

您没有提供足够的详细信息,但我必须假设当您使用adb打印它时cat,您可能没有与尝试从应用程序中读取它时相同的用户ID和权限.我没有跟踪确切的实现细节(如果你愿意,可以在这里阅读这个模块的源代码),但其他变量可能会起作用.

医生说:

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

因此,流程/应用程序可以使用TrafficStats.setThreadStatsUid()以从该文件中获取更多行,但这需要MODIFY_NETWORK_ACCOUNTING权限.

  • @EJP另外,我认为在Android中,[每个应用程序都使用自己的用户ID运行](https://source.android.com/security/overview/kernel-security#the-application-sandbox),这样就可以解释不同的用户ID."*Android系统为每个Android应用程序分配一个唯一的用户ID(UID),并在单独的进程中以该用户身份运行.*" (2认同)

小智 -4

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

此时你可以尝试两件事:

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

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

    对此:

    char c = null;
    while ((c = (char)bufferedReader.read()) != null) {
        // print to console each char
        System.out.println("Line: " + c);
    }
    
    Run Code Online (Sandbox Code Playgroud)

看看会发生什么。

  • `readLine()` 读取直到下一个行终止符。其中两个连续将产生一个空行。``````。不是过早的零。`BufferedReader.read()` 返回 `int`,它不能为 null,`char` 也不能。答案没有意义,代码无法编译。 (2认同)