[Android] FileInputStream跟踪
1. 源起
需要跟踪FileInputStream的Read的Nativie实现,开始走了弯路,Java工程下的FileInputStream实现与Android工程的实现不同。另外,http://blog.chinaunix.net/uid-26926660-id-3326678.html中分析的很好。
2. java.io.FileInputStream
import libcore.io.Libcore;
import libcore.io.Streams;
@Override public int read() throws IOException {
return Streams.readSingleByte(this);
}
@Override public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {
return IoBridge.read(fd, buffer, byteOffset, byteCount);
}
继续跟踪Streams.readSingleByte和IoBridge.read
3. libcore.io.Streams
http://grepcode.com/file/repo1.maven.org/maven2/com.google.okhttp/okhttp/20120626/libcore/io/Streams.java
public static int readSingleByte(InputStream in) throws IOException {
byte[] buffer = new byte[1];
int result = in.read(buffer, 0, 1);
return (result != -1) ? buffer[0] & 0xff : -1;
}
这里用了InputStream.read(byte[], int, int),实际上还是调用的FileInputStream.read(byte[], int, int),最后还是调用IoBridge.read(byte[], int, int)
4. libcore.io.ioBridge
https://android.googlesource.com/platform/libcore/+/796f0d5a4e7b83c3efc5e587b6766977dc20b0c3/luni/src/main/java/libcore/io/IoBridge.java
/**
* java.io thinks that a read at EOF is an error and should return -1, contrary to traditional
* Unix practice where you'd read until you got 0 bytes (and any future read would return -1).
*/
public static int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws IOException {
Arrays.checkOffsetAndCount(bytes.length, byteOffset, byteCount);
if (byteCount == 0) {
return 0;
}
try {
int readCount = Libcore.os.read(fd, bytes, byteOffset, byteCount);
if (readCount == 0) {
return -1;
}
return readCount;
} catch (ErrnoException errnoException) {
if (errnoException.errno == EAGAIN) {
// We return 0 rather than throw if we try to read from an empty non-blocking pipe.
return 0;
}
throw errnoException.rethrowAsIOException();
}
}
5. libcore.io.Libcore
http://grepcode.com/file/repo1.maven.org/maven2/org.robovm/robovm-rt/0.0.2/libcore/io/Libcore.java#Libcore
package libcore.io;
public final class Libcore {
private Libcore() { }
public static Os os = new BlockGuardOs(new Posix());
}
到这里有点断片了,BlockGuardOs里面还有一些调用,这里参考了http://blog.chinaunix.net/uid-26926660-id-3326678.html文章,read操作是由Posix实现的。
6. Libcore.io.Posix
https://android.googlesource.com/platform/libcore/+/6c9b5377550a9649ed1532d1fcdfeba116c74ead/luni/src/main/java/libcore/io/Posix.java
public int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException {
if (buffer.isDirect()) {
return readBytes(fd, buffer, buffer.position(), buffer.remaining());
} else {
return readBytes(fd, NioUtils.unsafeArray(buffer), NioUtils.unsafeArrayOffset(buffer) + buffer.position(), buffer.remaining());
}
}
到这里就是native方法了。
7. src/main/native/libcore_io_Posix.cpp
https://android.googlesource.com/platform/libcore/+/721ceca2a52a3c27aa751476c8562e1e68088e15/luni/src/main/native/libcore_io_Posix.cpp
#include <unistd.h>
#include "ScopeBytes.h" static jint Posix_readBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount) {
ScopedBytesRW bytes(env, javaBytes);
if (bytes.get() == NULL) {
return -1;
}
int fd = jniGetFDFromFileDescriptor(env, javaFd);
return throwIfMinusOne(env, "read", TEMP_FAILURE_RETRY(read(fd, bytes.get() + byteOffset, byteCount)));
}
第一:return throwIfMinusOne(env, "write", TEMP_FAILURE_RETRY(write(fd, bytes.get() + byteOffset, byteCount)));
throwIfMinusOne与TEMP_FAILURE_RETRY是宏定义。
write是<unistd.h>中的C语言库函数
第二:ScopedBytesRW
https://android.googlesource.com/platform/libnativehelper/+/3d9d2148155c2e0b3bf51cd548f58f93d1199a4e/include/nativehelper/ScopedBytes.h
这个文件比较简单,仅仅include了JNIHelper.h,用来区分byte[]s与ByteBuffers的。
class ScopedBytesRW : public ScopedBytes<false> {
public:
ScopedBytesRW(JNIEnv* env, jobject object) : ScopedBytes<false>(env, object) {}
jbyte* get() {
return mPtr;
}
};
8. 本文链接
http://blog.csdn.net/xiaodongrush/article/details/10004997
[Android] FileInputStream跟踪的更多相关文章
- android 流程跟踪
#记录一下 Thread cur_thread = Thread.currentThread(); StackTraceElement stack[] = cur_thread.getStackTra ...
- Android内存管理(5)*官方教程:Logcat内存日志各字段含义,查看当前内存快照,跟踪记录内存分配,用adb查看内存情况时各行列的含义,捕获内存快照的3种方法,如何让程序暴漏内存泄漏的方法
Investigating Your RAM Usage In this document Interpreting Log Messages 内存分析日志中各消息的含 ...
- Android 8.0 功能和 API
Android 8.0 为用户和开发者引入多种新功能.本文重点介绍面向开发者的新功能. 用户体验 通知 在 Android 8.0 中,我们已重新设计通知,以便为管理通知行为和设置提供更轻松和更统一的 ...
- Android Studio 3.0 新特性
最新Android Studio版本是Android Studio 3.0,本文提供了所有新功能和更改的摘要. 所有这些功能都可以在最新的金丝雀版本中发布,但beta测试版本可能尚未提供. 核心IDE ...
- Android Mokoid Open Source Project hacking
/***************************************************************************** * Android Mokoid Open ...
- Android Studio 3.0 下载 使用新功能介绍
谷歌2017发布会更新了挺多内容的,而且也发布了AndroidStudio3.0预览版,一些功能先睹为快.(英语一般,有些翻译不太好) 下载地址 https://developer.android.g ...
- Android Studio3.0 新特性 ~ New Features in Android Studio Preview (译文)
原文地址:https://developer.android.google.cn/studio/preview/features/index.html 最新Android Studio版本是Andro ...
- [异常特工]android常见bug跟踪
前言 对app的线上bug的收集(友盟.云捕等)有时会得到这样的异常堆栈信息:没有一行代码是有关自身程序代码的.这使得对bug的解决无从下手,根据经验,内存不足OOM,Dialog关闭,ListVie ...
- android应用安全——(数据抓包)跟踪监控android数据包
转载博客:http://blog.csdn.net/xyz_lmn/article/details/8808169 web开发中Chrome.IE.firefox等浏览器都自带提供了插件帮助开发者跟踪 ...
随机推荐
- delphi 文件夹权限设置(执行一个小脚本的笨办法)
如题,研究了一天,也没再网上找到比较好的方式,自己做了一个.方法如下: 1.创建一个 cmd 命令文件.2.调用该命令. 代码如下: S:='echo y|cacls h: /t /c /g ev ...
- Spring Boot使用Druid和监控配置
Spring Boot默认的数据源是:org.apache.tomcat.jdbc.pool.DataSource 整体步骤: (1) -- Druid简单介绍,具体看官网: (2) ...
- ALV的html表头
在ALV的function的exporting里添加属性: I_CALLBACK_HTML_TOP_OF_PAGE = alv_top_of_page 定义form响应上述ALV属性 *&-- ...
- Ext JS学习第十七天 事件机制event(二)
此文仅有继续学习笔记: 昨天说了三种邦定事件的方法,今天说一下自定义事件 假设现在又这样的情景一个自定义的事件 没有用到事件处理的场景 母亲问孩子和不饿-> ...
- SAP HANA 开发者中心(Developer Center)入门指南
- guava中eventbus注解使用
guava是 google 几个java核心类库的集合,包括集合.缓存.原生类型.并发.常用注解.基本字符串操作和I/O等等.学会使用该库相关api的使用,能使我们代码更简洁,更优雅,本章节我们来谈谈 ...
- java concurrency: ThreadLocal及其实现机制
转载:http://shmilyaw-hotmail-com.iteye.com/blog/1703382 ThreadLocal概念 从字面上来理解ThreadLocal,感觉就是相当于线程本地的. ...
- ARM简介(科普文)
ARM简介[1] 1. ARM只卖知识产权,不卖(物理的,实质的)产品. 全世界100多家公司购买了ARM授权,包括三星,Freescale.NXP Semiconductors.STMicro ...
- 杭电ACM 2052 Picture
Picture Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- BZOJ 1669: [Usaco2006 Oct]Hungry Cows饥饿的奶牛( LIS )
裸的LIS ----------------------------------------------------------------- #include<cstdio> #incl ...