1.InputStream(字节流) 和Reader(字符流)
2.OutputStream(字节流) 和 Writer(字符流)
1.文件名
Java提供了File类 来表示一个文件(通过构造方法来指定路径)
绝对路径
目录与目录之间用 \ 表示,,也可以用 / ,形如D:xxxxxx的就是绝对路径
相对路径
..(当前路径的上一级路径) 和 . (当前路径) 表示的就是相对路径,需要注意的是相对路径要有参考(自身)
1.InputStream(字节流) 和Reader(字符流)
InputStream 是一个抽象类 ,因此要通过new子类FileInputStream来实例化,传递文件路径就是打开某个文件
如果打开成功,那么针对new出来的对象的操作就是针对文件的操作 (这个对象被称为句柄(Handler))
文件打开后一定要记得关闭!!!!
InputStream inputStream = new FileInputStream("./test2.txt");
inputStream.close();
为什么要关闭文件?
为了释放资源(文件描述符表)
一个进程会使用PCB来描述,PCB其中的一个属性是文件描述符表.这个表示一个数组,每个元素代表当前进程打开的文件,
每次打开文件都会占据一个数组的一个位置,(这个数组是存在上限的),如果一直不释放,就会导致进程后续打开文件失败
读文件(字节流) ->如果读取的是文本文件在不进行别的操作下是打印一堆数字,而不是文本
1.无参数版本,返回一个int(但其实是byte),如果读到文件末尾返回-1,正常是0-255
也就是说虽然返回的int类型,但是值是从0到255之间,而不是其他数值
2.一个参数版本,把文件读到的内容塞到数组里,返回值是int(读取成功的字节个数)
3.三个参数版本,把读到的数据往数组里塞,从off开始塞,塞len个
读取文件操作实例:
InputStream inputStream = new FileInputStream("./test2.txt");
byte[] b arr = new byte[1024];//1024个字节,也就是一次读取1KB
int len = inputStream.read(arr);
String str = new String(arr,0,len);//把读取到的二进制数据转换成成字符串
System.out.println(str);
inputStream.close();//关闭文件
上述方法还是存在隐患的,如果在多线程应用中,在read方法调用时出现问题抛异常,那么下面的close操作可能会执行不了,也就是这个线程永远占有这个文件资源
因此我们可以这么写:
//try catch完后会自动对这个文件关闭
try(InputStream inputStream = new FileInputStream(scoFile)){
}catch(IOException e){
e.printStackTrace();
}
Reader 的读取方式,与上面的区别是读取到的是字符,比如文件中存在"你好"这两个字符,Reader的方式可以直接读取然后打印,但是上述方法直接读取打印是一个个数字,这些就是二进制数据,因此需要经过特殊处理,比如把他们连成一个字符串然后打印
import java.io.*;
public class File3 {
public static void main(String[] args) throws IOException {
Reader reader = new FileReader("test2.txt");
char[] buffer = new char[1024];
int len = reader.read(buffer);
for (int i = 0; i < len; i++) {
System.out.println(buffer[i]);
}
reader.close();
}
}
2.OutputStream(字节流) 和 Writer(字符流)
本质都是通过new出对象然后调用写的方法
OutputStream new出的子类的write方法
与读文件操作类似注意
注意:每次写都会清空文件内容
使用Writer的write方法
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class File3 {
public static void main(String[] args) {
try(Writer writer = new FileWriter("test1.txt")){
writer.write("hello world");
}catch (IOException e){
e.printStackTrace();
}
}
}
上面两个写的方法类似,都是写入流,区别只是写入的方式,一个以字符写入,一个以字节写入,最后流的本质还是你要写入到的数据