I/O流
I/O流
I:intpt(输入)
O:output(输出)
流:数据(字节和字符) 8比特位=1字节 2字节=1 字符
硬盘-->内存 == 输入(读取Reader)
内存-->硬盘 == 输出(写入Writer)
| 字节流基类 | 字符流基类 |
|---|---|
| InputStream | Reader |
| OutputStream | Writer |
- 这些基类本身(抽象类)并不能用来创建实例执行输入输出,但是他们会成为模板
字节流
几乎所有文件的操作都是字节流完成的,部分文件因为需要读写字符串,需要用到字符流,但是
字节流(字符流底层也是字节流)也可以完成,不过是需要进行一部分额外的转换。
字节输出流 OutputStream
FileOutputStream
硬盘存储的所有文件均为二进制文件
FileOutputStream创建实例对象,会指向一个路径(相对或者绝对)的文件,如果该文件不存在会自动创建
FileOutputStream fos = new FileOutputStream("a.txt");
fos.write(97); //写入文件中的值为a,97经过转码ascll码,得到结果
fos.close() 关闭文件输出流,节约资源
FileOutputStream写入多个字节
FileOutputStream fos = new FileOutputStream(new File("a.txt"));
//FOS如果写入字节是正整数(0-127),写入文件中的结果会转为ascll码,
//如果是负数,则会连带其后一个数转为gbk
byte[] byte1 = new byte[]{65,-65}; //第一个正常转换ascll,第二个因为没有后续数字,所以文件显示为“?”
fos.write(byte1);
fos.flush();
System.out.println(Arrays.toString("你好,世界".getBytes()));
byte[] byte2 = new byte[]{-28, -67, -96, -27, -91, -67, -17, -68, -116, -28, -72, -106, -25, -107, -116}; //该数组为你好的而字节数组
fos.write(byte2);
//最终结果为 A夸綘濂斤紝涓栫晫 因为后续流接了上去,引起前面负数的连带,
//字节流输入最好不要用负数结尾
fos.close();
字节输入流续写
FileOutputStream fos = new FileOutputStream("src//IO流//a.txt",true);
字节输入流
FileInputStream
创建一个实例对象,该对象会指向一个目录的文件,如果该目录不存在,抛出File不存在
FileInputStream
try {
FileInputStream fis = new FileInputStream("a.txt");
{
byte[] bbuf = new byte[1024];
int hashRead = 0;
while((hashRead=fis.read(bbuf))>0){
System.out.print(new String(bbuf,0,hashRead));
}
字符输出流
Writer
FileWriter是Writer基类的子类OutputStream(字节流的转换流)的子类,是常用的,文件字节输出流
FileWriter fw = new FileWriter("b.txt");
//FileWriter fw = new FileWriter("b.txt",true);如果要续写的话,增加true,不会覆盖原有的文件,如果是false的话将会覆盖原有的文件
fw.write("人生是一场旅途");
fw.close(); //这里如果不关闭流的话,b.txt中没有任何内容,可以flush流,就会有内容。一般在close在彻底关闭之前会对流flush
字符输入流
Reader
FileReader是Reader基类的子类InputStream(字节流的转换流)的子类,是常用的,文件字节输入流
FileReader fr = new FileReader("src//IO流//a.txt");
int aa = 0;
while((aa=fr.read())!=-1){ //这是一个字节一个字节读的
System.out.print((char) aa);
}
char [] a = new char[100];
while(fr.read(a,0,a.length)!=-1){ //多个字节读
System.out.print(String.valueOf(a));
}
缓冲流
- 通过对字节和字符的输入输出流的包装来,提高性能。
- 字符流,字节流,每次读入或者写出一个字节/字符,都会进行一个从内存到硬盘(或者相反)的过程,缓冲流相当于,给他们增加了一个数组,多个字节/字符(相当与read()读取数组的例子),循环一边该过程。
-
缓冲流与输入输出多个字节,有些许不同,缓冲流字节可以根据电脑性能弹性控制
转换流
-
转换流的两个方法可以指定,输入输出的编(utf-8或者gbk)
io流提供了两个转换流,这两个转换流用于实现将字节流转换为字符流。
字节流比字符流的使用宽泛很多,所以,只有在字符流更加方便的情况下,才会将字节流转换为字符流。比如,从txt文件中读取文本,或者写入,如果是二进制,需要在写入前以及读入进行包装(如果一次性操作不玩,需要多次调用转换方法)
但是,转换流,在源头进行包装,一次操作就不需要过多重复调用转换方法。
输入流以及输出流包装方法
InputStreamRead|OutputStreamWriter|
--|---|---
//转换流输入
public static void main(String[] args) throws IOException {
InputStreamReader reader = new InputStreamReader(System.in,"gbk"); //设置读取字符串为gbk
// reader.read()
// char[] tmp = new char[1];
int tmp = 0;
while((tmp =reader.read())!=-1){
System.out.print((char) tmp);
}
}
//转换流输出
FileOutputStream fis = null;
OutputStreamWriter osw = null;
try {
fis = new FileOutputStream("keyintest.txt",true);
osw = new OutputStreamWriter(fis,"gbk");
osw.write("我的世界");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
RandomAccessFile
- 随机访问文件(任意访问文件)
RandomAccsessFile提供了InputStream和OutputStream的三种read和writer方法- 它可以,改变文件指针。
RandomAccessFile在创建对象的时候需要指定一个mode参数,该参数指定Random的访问
模式
| 参数 | 作用 |
|---|---|
| r | 只读 |
| rw | 读写 |
| rws | 读写(每步都会直与底层同步) |
| rwd | 读写(每步都会直与底层同步) |
-
注意:如果RandonAccessFile想要在,文档中间插入的话,在确定插入指针之后,需要用一个临时文件将之后的内容全部保存,因为,该对象直接插入会覆盖之后的内容
例子:
public static void main(String[] args) throws IOException {
RandomAccessFile rsf = new RandomAccessFile("src//IO流//RandomAccessFileTest.java","rw");
byte[] tmpByte = new byte[100];
int pointValue = -1;
int tmp = -1;
while (rsf.read(tmpByte)!=-1){
System.out.print(new String(tmpByte)+"\n-----------------\n");//这里
if ((tmp=new String(tmpByte).indexOf("这里"))!=-1){
pointValue = (int) rsf.getFilePointer();
// pointValue=pointValue- (tmpByte.length-3*tmp);
System.out.print("指针节点--"+pointValue);
System.err.print(tmp);
break;
}
}
if (pointValue != -1) {
rsf.write("\n\n\n\n".getBytes());
for (int i = 0;i<20;i++){
rsf.write("w".getBytes());
}
// rsf.write("\n123\n".getBytes());
}
}
对象序列化的引用
- 对象可以保存在磁盘上,即为序列化。
- 从磁盘上恢复该java对象,即为反序列化
- 某个类需要实例化,该类必须实现两个接口的其中一个
- Serializable
- Externalizable
白茶清欢无别事,我在等风也等你。

浙公网安备 33010602011771号