面試題
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是句柄