FileInputStream在使用完以后,不关闭流,想二次使用可以怎么操作?

2019-12-19 21:22:41 浏览数 (1)

面试题

代码语言:javascript复制
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * FileInputStream在使用完以后,不关闭流,想二次使用可以怎么操作?
 * @author dhb
 */
public class FileInputStreamDemo {

    public static void main(String[] args) throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
        String parentPath = "";
        String text1Path = parentPath   "text1.txt";
        String text2Path = parentPath   "text2.txt";
        String text3Path = parentPath   "text3.txt";

        FileInputStream text1InputStream = new FileInputStream(text1Path);
        FileOutputStream text2OutputStream = new FileOutputStream(text2Path);
        FileOutputStream text3OutputStream = new FileOutputStream(text3Path);

        int len;
        byte[] bytes = new byte[1024];
        while ((len = text1InputStream.read(bytes)) != -1) {
            text2OutputStream.write(bytes, 0, len);
        }
        Class<? extends FileInputStream> inputStreamClass = text1InputStream.getClass();
        Field fd = inputStreamClass.getDeclaredField("fd");
        fd.setAccessible(true);
        Object o = fd.get(text1InputStream);
        System.out.println(o.hashCode());

        if (text1InputStream.read() == -1) {
            Method open0 = inputStreamClass.getDeclaredMethod("open0", String.class);
            open0.setAccessible(true);
            open0.invoke(text1InputStream, text1Path);
        }
        Object o1 = fd.get(text1InputStream);
        System.out.println(o1.hashCode());

        while ((len = text1InputStream.read(bytes)) != -1) {
            text3OutputStream.write(bytes, 0, len);
        }

        text2OutputStream.flush();
        text2OutputStream.close();

        text3OutputStream.flush();
        text3OutputStream.close();
    }

}

open和read执行流程

总结

FileInputStream通过再次open能实现重读的原理是:底层代码重新打开了一次文件,返回文件描述符(Linux)或句柄,这个值存在FileInputStream中的一个类型为FileDescriptor的对象中,FileDescriptor的fd是文件描述符,handle是句柄

0 人点赞