IO框架(1)

IO框架

课程目标

  1. 流的概念
  2. 流的分类
  3. 字节流
  4. 编码方式
  5. 字符流
  6. File流

什么是流

概念:内存与储存设备之间传输数据的通道

流的分类

按方向【重点】:

输入流:将<储存设备>中的内容读入到<内存>中。

输出流:将<内存>的内容写入到<储存设备>中。

按单位:

字节流:以字节为单位,可以读写所有数据。

字符流:以字符为单位,只能读写文本数据。

按功能:

节点流:具有实际传输数据的读写功能。

过滤流:在节点流的基础上增强功能。

字节流

字节流的父类(抽象类):

InputStream:字节输入流

OutputStream:字节输出流

FileInptuStream的使用

FileInputStream:

public int read (byte[] b) // 从流中读取多个字节,将读到内容输入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回 - 1.

FileOutputStream:

public viod write(byte[] b) //一次写多个字节,将b组的所有字节,写入输入流

package IO.IO1;

import java.io.FileInputStream;

/**
 * 演示FileInputStream的使用
 * 文件字节输入流
 */

public class Demo01 {
    public static void main(String[] args)  throws Exception {
        //1创建FileInputStream,并指定文件路径
        FileInputStream fis = new FileInputStream("d:\\aaa.txt");
//        //2读取文件
//        //2.1单个字节读取
//        //fis.read()
//        int data = 0;
//        while((data = fis.read())!=-1){
//            System.out.println((char) data);
//        }

        //2.2一次读取多个字节
//
//        byte[] buf = new byte[3];
//
//        int count = fis.read(buf);
//        System.out.println(new String(buf));
//        System.out.println(count);
//
//        int count2 = fis.read(buf);
//        System.out.println(new String(buf));
//        System.out.println(count2);
//
//        int count3 = fis.read(buf);
//        System.out.println(new String(buf,0,count3));
//        System.out.println(count3);

        byte[] buf = new byte[3];
        int count = 0;
        while((count = fis.read(buf))!=-1){
            System.out.println(new java.lang.String(buf,0,count));
        }
        //3关闭
        fis.close();
        System.out.println("执行完毕");
    }
}

FileOutStream的使用

package IO.IO1;

import java.io.FileOutputStream;

public class Demo02 {
    public static void main(String[] args) throws Exception{
        //1创建文件字节输出流对象
        //FileOutputStream fos = new FileOutputStream("d:\\bbb.txt");
        //会覆盖
        FileOutputStream fos = new FileOutputStream("d:\\bbb.txt",true);
        //不会覆盖
//        //2输入文件
//        fos.write(97);
//        fos.write('b');
//        fos.write('c');

        String string = "helloworld";
        fos.write(string.getBytes());
        //3关闭
        fos.close();
        System.out.println("执行完毕");
    }

}

字节流复制文件

package IO.IO1;

import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Demo03 {
    public static void main(String[] args) throws Exception {
        //1创建流
        FileInputStream fis = new FileInputStream("d:\\001.jpg");
        //1.2文件字节输出流
        FileOutputStream fos = new FileOutputStream("d:\\002.jpg");
        //2一边读,一边写
        byte[] buf = new byte[1024];//字节数组
        int count = 0;
        while((count = fis.read(buf))!=-1){
            fos.write(buf,0,count);//指定的数组中偏移的个数  指定的数组的下标  存储数据的长度
        }
        //3关闭
        fis.close();
        fos.close();
        System.out.println("执行完毕");
    }
}

字节缓冲流

缓冲流:BufferedInputStream/BufferedOutputStream

提高IO效率,减少访问磁盘的次数;

数据存储在缓冲区中,flush是将缓存区的内容写入文件中,也可以直接close。

BufferedInputStream的使用

package IO.IO1;

import java.io.BufferedInputStream;
import java.io.FileInputStream;

/**
 * 使用字节缓冲流读取
 */

public class Demo04  {
    public static void main(String[] args) throws Exception{
        //1创建BufferedInputStream
        FileInputStream fis = new FileInputStream("d:\\aaa.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
        //2读取
//        int data = 0;
//        while((data = bis.read())!=-1){
//            System.out.println((char)data);
//        }
        //2.1自创缓冲区
        byte[] buf = new byte[1024];
        int count = 0;
        while((count = bis.read(buf))!=-1){
            System.out.println(new String(buf,0,count));
        }
        //3关闭
        bis.close();
    }
}

BufferedOutputStream的使用

package IO.IO1;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;

public class Demo05 {
    public static void main(String[] args) throws Exception{
        //1创建字节输出缓冲流
        FileOutputStream fos = new FileOutputStream("d:\\buffer.txt");
        BufferedOutputStream bos =new BufferedOutputStream(fos);
        //2写入文件
        for(int i = 0;i<10;i++){
            bos.write("helloworld\n".getBytes());//先写入缓冲区,大小8k
            bos.flush();//刷新到硬盘
        }
        //3关闭(内部调用flush方法)
        bos.close();
        System.out.println("执行完毕");
    }
}

对象流

对象流:ObjectOutputStream/ObjectInputStream

增强了缓冲区功能

增强了读写8种基本类型和字符串功能

增强了读写对象的功能:

readObject() 从流中读取一个对象

writeObject(Object obj) 向流中写入一个对象

使用流传输对象的过程成为序列化,反序列化。

序列化

package IO.IO1;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

/**
 * 使用ObjectOutputStream实现对象的序列化
 */
public class Demo06 {
    public static void main(String[] args) throws Exception{
        //1创建对象六
        FileOutputStream fos = new FileOutputStream("d:\\stu.bin");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        //2序列化(写入操作)
        Student zhangsan = new Student("张三",20);
        oos.writeObject(zhangsan);
        //3关闭
        oos.close();
        System.out.println("序列化完毕");

    }

}

异常:

NotSerializableException

学生类无法实例化

可以通过

implements Serializable

继承Serializable使学生类可以实例化

反序列化

package IO.IO1;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
/**
 * 使用ObjectInputStream实现啊反序列化(读取重构成对象)
 */
public class Demo07 {
    public static void main(String[] args) throws Exception{
        //1创建对象流
        FileInputStream fis = new FileInputStream("d:\\stu.bin");
        ObjectInputStream ois = new ObjectInputStream(fis);
        //2读取文件(反序列化)
        Student s = (Student)ois.readObject();
        //3关闭
        ois.close();
        System.out.println("执行完毕");
        System.out.println(s.toString());
    }
}

序列化和反序列化注意事项

注意事项:
(1)序列化类必须要实现Serializable接口

(2)序列化类中对象属性也要实现Serializable接口

(3)序列化版本号ID,保证序列化的类和反序列化的类使同一个类

private static final long serialVersionUID = 1021110L;

异常:

InvalidClassException

类的版本号不同

UID改为异常提示的

IO.IO1.Student; local class incompatible: stream classdesc serialVersionUID = -2773328724821145463

private static final long serialVersionUID = -2773328724821145463L;

(4)使用transient(瞬间的)修饰属性,这个属性不能序列化

transient private int age;

(5)静态属性不能序列化

(6)序列化多个对象

序列化(写入操作)
Student zhangsan = new Student("张三",20);
Student lisi = new Student("李四",20);
oos.writeObject(zhangsan);
oos.writeObject(lisi);

反序列化
Student s = (Student)ois.readObject();
Student s2 = (Student)ois.readObject();

ois.close();
System.out.println("执行完毕");
System.out.println(s.toString());
System.out.println(s2.toString());

这样比较麻烦

改进

序列化
Student zhangsan = new Student("张三",20);
Student lisi = new Student("李四",20);

ArrayList<Student> list = new ArrayList<>();
list.add(zhangsan);
list.add(lisi);

反序列化
ArrayList<Student> list =(ArrayList<Student>)ois.readObject();

ois.close();
System.out.println("执行完毕");
System.out.println(list.toString());

字符编码

ISO-8859-1 收录除ASCII外,还包括修,希腊语,台语,阿拉伯语,希伯来语对应的文字符号

UTF-8 针对Unicode码表的可变长度字符编码

GB2312 简体中文

GBK 简体中文,扩充

BIG5 台湾,繁体中文

当编码方式和解码方式不一致时,会出现乱码。

字符流抽象类

字符流的父类(抽象类):

Reader:字符输入流

public int read(){}

public int read(char[] c){}

public int read(char[] b,int off,int len){}

Writer:字符输出流

public void write(int n){}

public void write(String str){}

public void write(char[] c){}

//UTF-8  12个字节4个汉字3个字节一个汉字,而这里是一个字节一个字节读,所以会乱码

文件字符流

FileReader:

public int read(char[] c)

从流中读取多个字符,将读到内容存入c数组,返回实际读到的字符数;如果达到文件的尾部,则返回 - 1。

FileWriter:

public void write(String str)

一次写多个字符,将b数组中所有字符,写入输出流。

package IO.IO2;

import java.io.FileReader;

public class Demo02 {
    public static void main(String[] args) throws Exception{
        //1创建FileReader 文件字符输入流
        FileReader fr = new FileReader("d:\\hello.txt");
        //2读取
        //2.1单个字符读取
//        int data = 0;
//        while((data = fr.read())!=-1){//读取一个字符
//            System.out.print((char)data);
//        }
        char[] buf = new char[1024];
        int count = 0;
        while((count = fr.read(buf))!=-1){
            System.out.println(new java.lang.String(buf,0,count));
        }
        //3关闭
        fr.close();
    }
}

FileWriter的使用

package IO.IO2;

import java.io.FileWriter;

public class Demo03 {
    public static void main(String[] args) throws Exception{
        //1.创建FileWriter对象
        FileWriter fw = new FileWriter("d:\\write.txt");
        //2.写入
        for (int i = 0;i<10;i++){
            fw.write("java是世界上最好的语言\r\n");
            fw.flush();
        }
        fw.close();
        System.out.println("执行完毕");
    }
}

字符流复制文件

使用FileReader和FileWriter复制文本文件,不能复制图片或二进制文件

因为FileReader是读取字符,会把二进制(1011011)数读成乱码

package IO.IO2;

import java.io.FileReader;
import java.io.FileWriter;

/**
 * 使用FileReader和FileWriter复制文本文件,不能复制图片或二进制文件
 */

public class Demo04 {
    public static void main(String[] args) throws Exception{
        //1创建FileReader FileWriter
        FileReader fr = new FileReader("d:\\write.txt");
        FileWriter fw = new FileWriter("d:\\write2.txt");
        //2读写
        int data = 0;
        while((data = fr.read())!=-1){
            fw.write(data);//fr读取write,fw写进write2
            fw.flush();
        }
        //3关闭
        fr.close();
        fw.close();
        System.out.println("复制完毕");

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值