[Android] FileInputStream tracking

Source: Internet
Author: User

1. Source

We need to track the Nativie Implementation of FileInputStream's Read and start to take a detour. The implementation of FileInputStream in the Java project is different from that in the Android project. In addition, the analysis in http://blog.chinaunix.net/uid-26926660-id-3326678.htmlis very good.

 


2. java. io. FileInputStream

[Java]
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 );
}

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 );
} Continue tracking Streams. readSingleByte and IoBridge. read

 


3. libcore. io. Streams

Http://grepcode.com/file/repo1.maven.org/maven2/com.google.okhttp/okhttp/20120626/libcore/io/Streams.java

[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;
}

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 is used here. read (byte [], int, int), actually called FileInputStream. read (byte [], int, int), and finally call 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]
/**
* Java. io thinks that a read at EOF is an error and shoshould return-1, contrary to traditional
* Unix practice where you 'd read until you got 0 bytes (and any future read wowould 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 ();
}
}

/**
* Java. io thinks that a read at EOF is an error and shoshould return-1, contrary to traditional
* Unix practice where you 'd read until you got 0 bytes (and any future read wowould 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


[Java]
Package libcore. io;
 
Public final class Libcore {
Private Libcore (){}
 
Public static OS OS = new BlockGuardOs (new Posix ());
}

Package libcore. io;

Public final class Libcore {
Private Libcore (){}

Public static OS OS = new BlockGuardOs (new Posix ());
}
This is a bit broken. BlockGuardOs has some calls,
 

 


6. Libcore. io. Posix

Https://android.googlesource.com/platform/libcore/+/6c9b5377550a9649ed1532d1fcdfeba116c74ead/luni/src/main/java/libcore/io/Posix.java

[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 ());
}
}

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 ());
}
}

Here is the native method.

 


7. src/main/native/libcore_io_Posix.cpp

Https://android.googlesource.com/platform/libcore/+/721ceca2a52a3c27aa751476c8562e1e68088e15/luni/src/main/native/libcore_io_Posix.cpp


[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 )));
}

# 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 )));
}


First: return throwIfMinusOne (env, "write", TEMP_FAILURE_RETRY (write (fd, bytes. get () + byteOffset, byteCount )));

ThrowIfMinusOne and TEMP_FAILURE_RETRY are macro definitions.


Write is the C language library function in <unistd. h>.

Second: ScopedBytesRW

Https://android.googlesource.com/platform/libnativehelper/+/3d9d2148155c2e0b3bf51cd548f58f93d1199a4e/include/nativehelper/ScopedBytes.h

This file is relatively simple. It only includes JNIHelper. h to distinguish byte [] s from ByteBuffers.

[Cpp]
Class ScopedBytesRW: public ScopedBytes <false> {
Public:
ScopedBytesRW (JNIEnv * env, jobject object): ScopedBytes <false> (env, object ){}
Jbyte * get (){
Return mPtr;
}
};

Class ScopedBytesRW: public ScopedBytes <false> {
Public:
ScopedBytesRW (JNIEnv * env, jobject object): ScopedBytes <false> (env, object ){}
Jbyte * get (){
Return mPtr;
}
};

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.