FileInputStream在使用完以后,不关闭流,想二次使用可以怎么操作?
- 2019 年 12 月 19 日
- 筆記
面试题
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是句柄