使用FileInputStream实现文件读取Demo:
package com.anbai.sec.filesystem;import java.io.*;/*** Creator: yz* Date: 2019/12/4*/public class FileInputStreamDemo {public static void main(String[] args) throws IOException {File file = new File("/etc/passwd");// 打开文件对象并创建文件输入流FileInputStream fis = new FileInputStream(file);// 定义每次输入流读取到的字节数对象int a = 0;// 定义缓冲区大小byte[] bytes = new byte[1024];// 创建二进制输出流对象ByteArrayOutputStream out = new ByteArrayOutputStream();// 循环读取文件内容while ((a = fis.read(bytes)) != -1) {// 截取缓冲区数组中的内容,(bytes, 0, a)其中的0表示从bytes数组的// 下标0开始截取,a表示输入流read到的字节数。out.write(bytes, 0, a);}System.out.println(out.toString());}}
输出结果如下:
## User Database## Note that this file is consulted directly only when the system is running# in single-user mode. At other times this information is provided by# Open Directory.## See the opendirectoryd(8) man page for additional information about# Open Directory.#nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/falseroot:*:0:0:System Administrator:/var/root:/bin/shdaemon:*:1:1:System Services:/var/root:/usr/bin/false.....内容过长省去多余内容
调用链如下:
java.io.FileInputStream.readBytes(FileInputStream.java:219)java.io.FileInputStream.read(FileInputStream.java:233)com.anbai.sec.filesystem.FileInputStreamDemo.main(FileInputStreamDemo.java:27)
其中的readBytes是native方法,文件的打开、关闭等方法也都是native方法:
private native int readBytes(byte b[], int off, int len) throws IOException;private native void open0(String name) throws FileNotFoundException;private native int read0() throws IOException;private native long skip0(long n) throws IOException;private native int available0() throws IOException;private native void close0() throws IOException;
java.io.FileInputStream类对应的native实现如下:
JNIEXPORT void JNICALLJava_java_io_FileInputStream_open0(JNIEnv *env, jobject this, jstring path) {fileOpen(env, this, path, fis_fd, O_RDONLY);}JNIEXPORT jint JNICALLJava_java_io_FileInputStream_read0(JNIEnv *env, jobject this) {return readSingle(env, this, fis_fd);}JNIEXPORT jint JNICALLJava_java_io_FileInputStream_readBytes(JNIEnv *env, jobject this,jbyteArray bytes, jint off, jint len) {return readBytes(env, this, bytes, off, len, fis_fd);}JNIEXPORT jlong JNICALLJava_java_io_FileInputStream_skip0(JNIEnv *env, jobject this, jlong toSkip) {jlong cur = jlong_zero;jlong end = jlong_zero;FD fd = GET_FD(this, fis_fd);if (fd == -1) {JNU_ThrowIOException (env, "Stream Closed");return 0;}if ((cur = IO_Lseek(fd, (jlong)0, (jint)SEEK_CUR)) == -1) {JNU_ThrowIOExceptionWithLastError(env, "Seek error");} else if ((end = IO_Lseek(fd, toSkip, (jint)SEEK_CUR)) == -1) {JNU_ThrowIOExceptionWithLastError(env, "Seek error");}return (end - cur);}JNIEXPORT jint JNICALLJava_java_io_FileInputStream_available0(JNIEnv *env, jobject this) {jlong ret;FD fd = GET_FD(this, fis_fd);if (fd == -1) {JNU_ThrowIOException (env, "Stream Closed");return 0;}if (IO_Available(fd, &ret)) {if (ret > INT_MAX) {ret = (jlong) INT_MAX;} else if (ret < 0) {ret = 0;}return jlong_to_jint(ret);}JNU_ThrowIOExceptionWithLastError(env, NULL);return 0;}
完整代码参考OpenJDK:openjdk/src/java.base/share/native/libjava/FileInputStream.c
