我正在尝试阅读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
为什么?
答案 0 :(得分:13)
我正在尝试阅读Android 6中的
/proc/net/xt_qtaguid/stats
。
在Linux中,/proc/
下的文件实际上不是文件:它们由procfs
处理,ls -l
是一个特殊的文件系统,每次读取或写入文件条目时执行代码 (代码是内核模块中定义的回调函数)。因此,这些伪文件不像常规文件那样是静态的,而是完全动态。大小提供了一个有趣的线索:(大部分)这些文件的长度为0 (如cat
所示),但在阅读时会显示一些内容。
简而言之,可以预期从2个不同的上下文中读取同一个文件会产生2种不同的结果。
在这种情况下,"文件"回调由xt_qtaguid
module for Android处理,管理"每个应用程序/委托数据使用监控"。
这个虚拟文件的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),但其他变量可能会发挥作用。
对于提供网络数据传输作为服务的应用程序(例如下载管理器,媒体流服务等),可以使用以下内容将网络数据传输的所有权归属于请求应用程序的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应该在这两行之间增加一条线。
此时你可以尝试两件事:
改变这个:
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);
}
看看会发生什么。