我们使用IO,都是要先打开:
//打开流
FileInputStream fileInputStream = new FileInputStream(new File(fileName));
读写:
int by = 0;
byte []bytes = new byte[10];
// 一个字节数组的读出数据
while ((by = fileInputStream.read(bytes)) != -1){
System.out.print((new String(bytes, 0, by)));
}
使用完毕了就要关闭:
//关闭流
fileInputStream.close();
IO的使用大概就是这三个过程。
首先来一个正常的IO完整操作:
我来复现这个操作,我预先在F:\\HelloCoder-HaC.txt 文件写入以下内容:
HelloCoder ,I am hh
My webSite is https://blog.csdn.net/qq_42543063
注意这里是FileInputStream,是一个字节流不要出现中文字符否则会乱码
写一下代码:
public class InputStreamTest {
public static void main(String[] args) throws IOException {
String fileName = "F:\\HelloCoder-HaC.txt";
File file = new File(fileName);
if (!file.exists()) {
file.mkdir();
}
FileInputStream fileInputStream = new FileInputStream(new File(fileName));
int by = 0;
byte[] bytes = new byte[10];
// 一个字节数组的读出数据
// 第一次读写
while ((by = fileInputStream.read(bytes)) != -1) {
System.out.print((new String(bytes, 0, by)));
}
//关闭流后如何打开,利用反射
System.out.println();
System.out.println("-------重新复用流-------");
// 第二次 重新读写
bytes = new byte[10];
while ((by = fileInputStream.read(bytes)) != -1) {
System.out.print((new String(bytes, 0, by)));
}
}
}
输出:
HelloCoder ,I am HaC
My webSite is https://rain.baimuxym.cn
-------重新复用流-------
很明显看到这个第二次的输出是没有任何结果的。
回到问题:
要重新复用流,那肯定就不能重新new FileInputStream,我想到的是使用反射,如果对反射不熟悉的,建议看一下:
Java的反射是个什么东西???
那反射要实现,需要获取哪个方法呢?我们看一下FileInputStream 的源码:
public FileInputStream(File file) throws FileNotFoundException {
String name = (file != null ? file.getPath() : null);
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(name);
}
if (name == null) {
throw new NullPointerException();
}
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
fd = new FileDescriptor();
fd.attach(this);
path = name;
open(name);
}
private void open(String name) throws FileNotFoundException {
open0(name);
}
/**
* Opens the specified file for reading.
* @param name the name of the file
*/
private native void open0(String name) throws FileNotFoundException;
FileInputStream 在最后会通过open(name) 这个方法打开文件,open()会调用open0(), open0()是一个native方法,实现不是java,看到注释,大概的意思就是指定文件路径,然后可以打开进行读操作。
既然知道open() 方法,那就可以用反射了,注意这个方法是private。
知道方法那就很容易了。
解决:
代码如下:
public class InputStreamTest {
public static void main(String[] args) throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
String fileName = "F:\\HelloCoder-HaC.txt";
File file = new File(fileName);
if (!file.exists()) {
file.mkdir();
}
FileInputStream fileInputStream = new FileInputStream(new File(fileName));
int by = 0;
byte[] bytes = new byte[10];
// 一个字节数组的读出数据
// 第一次读写
while ((by = fileInputStream.read(bytes)) != -1) {
System.out.print((new String(bytes, 0, by)));
}
// //关闭流,这里关闭也不影响
fileInputStream.close();
//关闭流后如何打开,利用反射
System.out.println();
System.out.println("-------重新复用流-------");
// 第二次 重新读写
Class in = fileInputStream.getClass();
Method openo = in.getDeclaredMethod("open", String.class);
//因为是private
openo.setAccessible(true);
openo.invoke(fileInputStream, fileName);
bytes = new byte[10];
while ((by = fileInputStream.read(bytes)) != -1) {
System.out.print((new String(bytes, 0, by)));
}
}
}
输出:
HelloCoder ,I am HaC
My webSite is https://rain.baimuxym.cn
-------重新复用流-------
HelloCoder ,I am HaC
My webSite is https://rain.baimuxym.cn