按方向【重点】:
输入流:将<存储设备>中的内容读入到<内存> 中;
输出流:将<内存>中的内容写入到<存储设备>中;
按单位:
按功能:
字节流的父类(抽象类):
InputStream:字节输入流
public int read(){}
public int read(byte[] b){}
public int read(byte[] b , int off , int len){}
OutputStream:字节输出流
public void write(int n){}
public void write(byte[] b){}
public void write(byte[] b , int off , int len){}
FileOutputStream:
import java.io.FileOutputStream;
import java.io.IOException;
public class TestFileOutPutStream {
public static void main(String[] args) throws IOException {
//1.输出字节流OutPutStream
//2.输出字节节点流 具有实际传输数据的功能(文件路径,boolean append) true代表追加不覆盖
//路径正确:但是文件不存在,则会自动创建一个文件,但目录和盘符要提前有
FileOutputStream fos = new FileOutputStream("D:\\JAVAEE\\Study\\Study\\com\\qf\\Day31\\test.txt");
//相对路径:"Files\\test.txt" 与上一种形式等级,相对于当前项目的路径下,寻找该路径和文件
// FileOutputStream fos = new FileOutputStream("Files\\test.txt");
fos.write(65);
fos.write(66);
fos.write(67);
fos.write('D');
byte[] bytes = new byte[] {65,66,67,68,'G'};
// fos.write(bytes);//一次输出一组字节
// 字节数组 起始下标 长度
fos.write(bytes, 1, 3);
// String s = "你";
// byte[] bs = s.getBytes();
// System.out.println(bs[0] +"\t"+bs[1]);
// fos.write(bs);
fos.close();
}
}
运行后完成了文件的创建和数据的写入。
FileInputStream:
import java.io.FileInputStream;
import java.io.IOException;
public class TestFileInputStream {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("D:\\JAVAEE\\Study\\Study\\com\\qf\\Day31\\test.txt");
//读到了-1,就代表了文件末尾
// while(true) {
// int n = fis.read();//一次读一个字节
// if(n == -1) {//文件末尾
// break;//停止读的操作
// }
// System.out.println((char)n);
// }
byte[] bytes = new byte[4];//该数组作为读取时的存储
while(true) {
int count = fis.read(bytes);//每次读取到的有效字节个数
if(count == -1) {
break;
}
//读多少个,打印多少个
for(int i = 0 ; i < count ; i++) {
System.out.println((char)bytes[i]+"\t");
}
System.out.println();
}
fis.close();
}
}
输入结果:
A
B
C
D
B
C
D
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestFileIO {
public static void main(String[] args) throws IOException {
// 将指定图片,上传一份到项目里来
//文件是在存储设备中的--》读到程序中来--》写入到存储设备中
FileInputStream fis = new FileInputStream("C:\\Users\\xuhao\\Desktop\\千锋教育Java2002逆战班(20200203)\\打卡\\第六周\\26\\博客.png");
//223KB
//缓冲空间过大过小都容易有小问题
// byte[] cache = new byte[1024*223];
// fis.read(cache);
//输出流
FileOutputStream fos = new FileOutputStream("Files\\博客.png");
// fos.write(cache);
int len = 0;//代表每次读到的字节
while((len = fis.read()) != -1) {//只要不读到-1
fos.write(len);//读多数写多少
}
fis.close();
fos.close();
}
}
缓冲流:BufferedOutputStream / BufferedInputStream
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestBufferOutput {
public static void main(String[] args) throws IOException {
//有参构造需要一个字节输出节点流
//先创建字节输出节点流
FileOutputStream fos = new FileOutputStream("Files/buff.txt");
//增强节点流
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write('A');
bos.write('B');
bos.flush();//刷新缓冲区(将缓冲区的数据,一次性写入到文件中,并清空当前缓冲区)
bos.write('C');
bos.write('D');
bos.close();//级联的执行了flush();释放资源的同时,将缓冲区的数据一次性写入到文件里
//-----------------------------------------
FileInputStream fis = new FileInputStream("Files/buff.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
byte[] bytes = new byte[100];
int count = bis.read(bytes);
for(int i = 0 ; i < count ; i++) {
System.out.println(bytes[i]);
}
}
}
输出结果:
65
66
67
68
对象流:ObjectOutputStream / ObjectInputStream
使用流传输对象的过程称为序列化、反序列化;
对象序列化的细节:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
public class TestObjectStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {
OutputStream os = new FileOutputStream("Files/obj.txt");
ObjectOutputStream oos = new ObjectOutputStream(os);
// oos.writeInt(60);
// oos.writeDouble(6.6);
// oos.writeBoolean(true);
Student stu1 = new Student("Tom" , 22 , "男" , 99D , new Address());
Student stu2 = new Student("Jack" , 21 , "男" , 95D , new Address());
Student stu3 = new Student("Rose" , 20 , "女" , 99D , new Address());
oos.writeObject(stu1);
oos.writeObject(stu2);
oos.writeObject(stu3);
oos.flush();
//------------
InputStream is = new FileInputStream("Files/obj.txt");
ObjectInputStream ois = new ObjectInputStream(is);
// int result = ois.readInt();
// System.out.println(result);
// Object obj1 = ois.readObject();
// System.out.println(obj1);
// Student s = (Student)obj1;
// System.out.println(s.name);
// Object obj2 = ois.readObject();
// System.out.println(obj2);
// Object obj3 = ois.readObject();
// System.out.println(obj3);
while(true) {
try {
Object obj = ois.readObject();
System.out.println(obj);
}catch(Exception e) {
//到达文件末尾 获取EOFException一次,就停止循环
break;//自定义处理异常
}
}
}
}
//对象要支持序列化
//属性也要支持序列化
class Student implements Serializable{//实现该接口已序列化,对static修饰的值进行序列化,则该值属于所有类,影响序列化
String name;
Integer age;
String sex;
Double score;
Address add;
//transient修饰的属性,不参与序列化
//基本数据类型的数组,可以序列化
//引用数据类型的数组,数组类型要支持序列化
public Student(String name, Integer age, String sex, Double score, Address add) {
super();
this.name = name;
this.age = age;
this.sex = sex;
this.score = score;
this.add = add;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", sex=" + sex + ", score=" + score + ", add=" + add + "]";
}
}
class Address implements Serializable{
String position;
String zipCode;
public Address() {}
public Address(String position, String zipCode) {
super();
this.position = position;
this.zipCode = zipCode;
}
}
输出结果:
Student [name=Tom, age=22, sex=男, score=99.0, add=com.qf.Day31.Address@b4c966a]
Student [name=Jack, age=21, sex=男, score=95.0, add=com.qf.Day31.Address@2f4d3709]
Student [name=Rose, age=20, sex=女, score=99.0, add=com.qf.Day31.Address@4e50df2e]