声明
在了解处理流的时候我们要了解一些基本内容,如上图的IO流体系所示,在图中,蓝色的。InputStream,OutputStram这二个是字节流的父类,Reader,Writer是字符流的父类,下方箭头代红色框内代表的是他们的子实现类,这些流是最基础的流!,一切的处理流都需要有基础流,才能实现功能。
缓冲流
作用,就是为了加快传输速度。以下代码做了不使用缓冲流和使用缓冲流的区别,首先要准备一个内存大小足够的文件(图片,音频,文档都可以)
字节缓冲流
文档准备:我的文档为59mb大小
不使用缓冲流的情况
代码如下
public static void main(String[] args) throws Exception {
// 注意字节流和字符流的区别
InputStream is=new FileInputStream("src/com/haogu/write.txt");
OutputStream os=new FileOutputStream("src/com/haogu/write2.txt");
System.out.println("在不使用缓冲流的情况下");
byte[] bytes=new byte[1024];
long start=System.currentTimeMillis();
int num;
while ((num=is.read(bytes))!=-1){
os.write(bytes);
};
long end=System.currentTimeMillis();
System.out.println("执行时间为"+(end-start)+"毫秒");
is.close();
os.close();
}
使用缓冲流的情况
public static void main(String[] args) throws Exception {
InputStream is=new FileInputStream("src/com/haogu/write.txt");
InputStream bis=new BufferedInputStream(is);
OutputStream os=new FileOutputStream("src/com/haogu/write2.txt");
OutputStream bos=new BufferedOutputStream(os);
Long start2=System.currentTimeMillis();
byte[] bytes=new byte[1024];
int num;
// 缓冲流处理 循环的时候就用缓冲流
while((num=bis.read(bytes))!=-1){
bos.write(bytes);
}
long end2=System.currentTimeMillis();
System.out.println("使用缓冲流执行时间为"+(end2-start2)+"毫秒");
bis.close();
is.close();
bos.close();
os.close();
}
可以看到,传输的速度极大的加快了。
字符缓冲流
字符缓冲流和字节缓冲流相比,字符缓冲流中多了一些方法,可以让我们更好处理文档的数据
在不使用缓冲流的情况下处理
public static void main(String[] args) throws Exception {
//字符缓冲流 ,二种处理方式
Reader re=new FileReader("src/com/haogu/java02/write.txt");
Writer wi=new FileWriter("src/com/haogu/java02/write2.txt");
char[] chars=new char[1024];
int num;
long start=System.currentTimeMillis();
System.out.println("不使用缓冲流使用最普通的流处理");
while((num=re.read(chars))!=-1){
wi.write(chars);
}
Long end=System.currentTimeMillis();
System.out.println("运行时间时间为"+(end-start)+"毫秒");
}
使用字符缓冲流但是不使用字符缓冲流中特有的方法来处理
使用字符缓冲流的新方法
因为文件里面是空的所以先运行一次之后才会读取到数据,否则只是插入数据,是读取不到数据的
public static void main(String[] args) throws Exception {
Reader r=new FileReader("src/com/haogu/java02/write3.txt");
// todo 使用BufferedReader内的方法来处理循环
BufferedReader br=new BufferedReader(r);
Writer w=new FileWriter("src/com/haogu/java02/write3.txt");
// todo 使用BufferedWrite内的方法来处理循环
BufferedWriter bw=new BufferedWriter(w);
// 按照行来读取
// readLine读取完毕之后读取的就是null
String num;
while ((num=br.readLine())!=null){
// 注意区别
System.out.println(num);
}
// 对于写入
// 换行
bw.write("随意内容");
bw.write("随意内容");
bw.write("随意内容");
bw.newLine();
bw.write("随意内容");
bw.write("随意内容");
bw.write("随意内容");
br.close();
r.close();
bw.close();
w.close();
}
运行二次之后就可以读出第一次的数据了,会发现第一次插入的数据是按照行来读取的
转换流
文档准备:
jdk默认的编码是utf-8在这里准备一个 编码格式是GBK的文档
转换输入流(读取)
使用默认方式读取
代码如下
public static void main(String[] args) throws Exception {
InputStream is=new FileInputStream("src/com/haogu/Java03/write3.txt");
int num;
byte[] bytes=new byte[100];
while ((num=is.read(bytes))!=-1){
System.out.println(new String(bytes,0,num));
}
is.close();
}
发现大部分乱码
使用转换流来读取
public static void main(String[] args) throws Exception {
InputStream is=new FileInputStream("src/com/haogu/Java03/write3.txt");
// 转换流都是吧字节流转化为字符流 传入的参数就是字节流,和需要你转换的格式
// 格式为 InputStreamReader
InputStreamReader ir=new InputStreamReader(is,"GBK");
System.out.println("用转换流来读取");
char[] chars=new char[100];
while ((ir.read(chars))!=-1){
System.out.println(new String(chars));
}
}
发现可以正常的读取
转换输出流
默认输出方式
public static void main(String[] args) throws Exception {
// 转换流输出
try( OutputStream os=new FileOutputStream("src/com/haogu/Java03/write3.txt",true);
) {
String str="用常规方式输入错误编码格式的内容";
byte[] bytes=str.getBytes();
os.write(bytes);
}catch (Exception e){
e.printStackTrace();
}
}
可以看到文件里面乱码了,这是因为jdk默认utf-8和GBK不兼容导致
使用转换流输入
代码如下
public static void main(String[] args) throws Exception {
try( OutputStream os=new FileOutputStream("src/com/haogu/Java03/write3.txt",true);
OutputStreamWriter ow=new OutputStreamWriter(os,"gbk")
) {
ow.write("/n传入正确的格式");
}catch (Exception e){
e.printStackTrace();
}
}
数据流
数据流:正常情况下我们只能往文件里面输入 普通的符合Unicode编码的值,而无法直接输入整形,浮点型,以及字符串等等,通过数据流可以实现这些不同类型的数据的传输,输入进去的数据是加密的 但是在读取的时候计算机是可以识别的 注意读取时候的注意事项,在代码中已经注释了
public static void main(String[] args) throws Exception {
// todo 数据流:正常情况下我们只能往文件里面输入 普通的符合Unicode编码的值,而无法直接输入
// 整形,浮点型,以及字符串等等,通过数据流可以实现这些不同类型的数据的传输,
// 输入进去的数据是加密的 但是在读取的时候计算机是可以识别的
try( OutputStream os=new FileOutputStream("src/com/haogu/Java04/write04.txt");
DataOutputStream dos=new DataOutputStream(os);
) {
dos.write(67);
dos.writeInt(132);
dos.writeLong(1111111111);
dos.writeBoolean(true);
dos.writeDouble(3.1415926);
dos.writeUTF("数据流的测试");
}catch (Exception e){
e.printStackTrace();
}
// todo 数据流的读取
try( InputStream is=new FileInputStream("src/com/haogu/Java04/write04.txt");
DataInputStream dis=new DataInputStream(is);
){
// todo 注意读取的时候必须根据你输入的顺序进行读取 否则会出现数据不准确或者报错
System.out.println(dis.read());
System.out.println(dis.readInt());
System.out.println(dis.readLong());
System.out.println(dis.readBoolean());
System.out.println(dis.readDouble());
System.out.println(dis.readUTF());
}catch (Exception e){
e.printStackTrace();
}
}
对象流(序列化)
对对象进行序列化的时候,对象要实现序列化的接口,否则会报序列化异常的错误
准备工作
准备一个类
public class Student implements Serializable {
private String name;
private Integer age;
private String sex;
public Student() {
}
public Student(String name, Integer age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
}
序列化’
代码如下
public static void main(String[] args) throws Exception {
Student student = new Student("张三",15,"男");
try(
OutputStream os=new FileOutputStream("src/com/haogu/java05/write05.txt");
ObjectOutputStream oos=new ObjectOutputStream(os);
){
// 记得让student实现序列化的接口
oos.writeObject(student);
}catch (Exception e){
e.printStackTrace();
}
}
一下是序列化得到的信息
反序列化
public static void main(String[] args) {
try (
InputStream is=new FileInputStream("src/com/haogu/java05/write05.txt");
ObjectInputStream ois=new ObjectInputStream(is);
){
System.out.println( ois.readObject());
}catch (Exception e){
e.printStackTrace();
}
}
序列化还可以得到无法打开的文件
public static void main(String[] args) {
Student student = new Student("张三", 15, "男");
try(
OutputStream os=new FileOutputStream("src/com/haogu/java05/write05.test");
ObjectOutputStream oos=new ObjectOutputStream(os);
){
oos.writeObject(student);
}catch (Exception e){
}
}
但是我们的程序可以正常去读取
读取
public static void main(String[] args) {
try(
InputStream is=new FileInputStream("src/com/haogu/java05/write05.test");
ObjectInputStream isr=new ObjectInputStream(is);
){
System.out.println(isr.readObject());
}catch (Exception e){
e.printStackTrace();
}
}