第十四章 I/O系统

一、I/O系统的分类

1.输入流:程序从输入流读取数据

   输出流:程序向输出流写入数据

2.字节流:数据流中的最小的数据单元是字节

   字符流:数据流中的最小单元是字符

3.节点流、处理流

二、I/O系统的四个抽象类

1.Java中提供的流类型在包java.io内,分别继承自四个抽象类

2.I/O系统的四个抽象类

字节流字符流
输入流InputStreamReader
输出流OutputStreamWriter

如果是多媒体文件我们使用字节流,因为字符流会破坏对媒体文件,而word文档这种文件还是主要使用的是字符流,因为中文不乱码

public class FileInputStreamTest {
    public static void main(String[] args)  {
        //我们使用的是字节流,而一个汉字等于一个字符,一个字符等于两个字节,而读取输出的时候会将
        //汉字拆开,所以控制台显示的时候时中文乱码,而往文件中写入的时候,由于文件不会打开,所以会将汉字的
        //两个字节组合为汉字,所以文件中中文不会乱码
        //文件输入字节流
        FileInputStream fis = null;
        //文件输出字节流
        FileOutputStream fos = null;
        try{//相对路径是从src开始的
            fis = new FileInputStream
                    ("src/com/haina365/lesson18/9..jpg");
            // ("src/main/java/com/haina365/lesson18/FileStreamTest.java");
            //如果输出的文件已经存在则直接写入,如果不存在,则新建文件在保存内容中
            fos = new FileOutputStream
                    ("src/com/haina365/lesson18/9.jpg");
            //   ("src/com/haina365/lesson18/text.txt");
            int a = 0;
            //read读取文件中的数据,都是大于0的数,当返回结构为-1时,表示读取结束
            while((a = fis.read()) != -1){
                fos.write(a);//将内存中的数据写入到文件
                System.out.print((char) a);
            }
        }catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}
public class FileReaderTest {
    public static void main(String[] args) {
        //文件输入字符流
        FileReader fr = null;
        //文件输入字符流
        FileWriter fw = null;
        try{
            fr = new FileReader
                    ("src/com/haina365/lesson18/9.jpg");
            //("src/main/java/com/haina365/lesson18/FileStreamTest.java");
            fw = new FileWriter
                    ("src/com/haina365/lesson18/1..jpg");
            // ("src/com/haina365/lesson18/demo.txt");
            int a = 0;
            while((a = fr.read()) != -1){
                fw.write(a);
                System.out.print((char)a);
            }
            fw.flush();//保存

        }catch (FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

三、节点流

节点流分类:

类型字节流字符流
文件

FileInputStream

FileOutputStream

FileReader

FileWriter

数组

ByteArrayInputStream

ByteArrayOutputStream

CharArrayReader

CharArrayWriter

字符串

StringReader

StringWriter

管道

PipedInputStream

PipedOutputStream

PipedReader

PipedWriter

四、文件流

1.FileInputStream类:从文件系统中的某个文件中获得输入字节

常用方法:

(1)int read()

(2)long skip(long n)

(3)void close()

2.FileOutputStream类:用于将数据写入文件的输出流

常用方法:

(1)void write(int b)

(2)void close()

3.FileReader类与FileWriter类为增加其它方法

五、装饰器模式

1.目的:解决过度依赖继承,难以用创建类的方式来进行对象的功能扩展的问题

2.实现方式:用对象数量换类的数量

3.应用场景:

(1)扩展一个类的功能,给一个类增加附加责任

(2)不单一依赖继承,增加由一些基本的排列组合产生大量的功能(需要创建很多功能类)

(3)对目标进行选择扩展,动态增加功能且可以动态撤销

4.优点:虽然装饰模式产生的初衷是装饰器类对默认目标实现类的行为扩展,装饰器类却并不对默认目标实现类形成依赖

5.缺点:增加了对象

(1)共同的父类(接口),导致创建的对象类似,给查错带来困难

(2)对象的创建增加了空间的开销

六、处理流

处理流分类

类型字节流字符流
过滤器(装饰器)

FileInputStream

FileOutputStream

FileReader(抽象类)

FileWriter(抽象类)

缓冲流

BufferedInputStream

BufferedOutputStream

BufferedReader

BufferedWriter

转换流

InputStreamReader

OutputStreamReader

数据流

DataInputStream

DataOutputStream

对象流

ObjectInputStream

ObjectOutputStream

打印流PrintStreamPrintWriter

七、缓冲流

1.BufferedInputStream类:创建一个内部缓冲区数组,默认为defaultBufferSize=8192相当于8k

(1)套接InputStream类型流

(2)常用方法:

               void mark(int readlimit)

               void reset()

2.BufferedOutputStream类:实现缓冲的输出流,应用程序就可以一次将多个字节写入文件系统

(1)套接OutputStream类型流

(2)常用方法: 

                 void flush()

3.BufferedReader类

套接Reader类型流,常用方法同BufferedInputStream类

String readLine()

4.BufferedWriter类

套接Writer类型流,常用方法同BufferedOutputStream类

void newLine()

public class BufferedInputStreamTest {
    //处理流要想正常必须要有节点流,因为节点流是真正具有输入输出功能的流,而
    //处理流只能增强输入输出功能,但是没有输入输出功能
    public static void main(String[] args) {
        //文件输入字节流
        FileInputStream fis = null;
        //缓冲输入字节流
        BufferedInputStream bis = null;
        //输入转换流
        InputStreamReader isr = null;
        //文件输入字节流
        FileOutputStream fos =null;
        //文件输出字节流
        BufferedOutputStream bos = null;
        //输出转换流
        OutputStreamWriter osw = null;
        try{
            fis = new FileInputStream
                    ("src/com/haina365/lesson19/BufferedInputStreamTest.java");
            //缓冲区底层是一个数组,大小为8k
            bis = new BufferedInputStream(fis);
            //处理流在使用的时候,谁先用谁后用没有顺序,可以随意使用
            //gbk utf-8 gb2312支持中文的编码集
            isr = new InputStreamReader(bis,"gbk");
            //在输出流的第二个参数上写true,就修改保存文档中的形式由覆盖变成了追加
            fos = new FileOutputStream("src/com/haina365/lesson19/text.txt",true);
            bos = new BufferedOutputStream(fos);
            osw = new OutputStreamWriter(bos,"gbk");
            int a =0;
            //注意有处理流后,用什么方式读数据,就用什么方式写数据
            while((a = isr.read()) != -1){
                osw.write(a);
                System.out.print((char)a);
            }
            osw.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

八、转换流

1.InputStreamReader类:它使用指定的字符集读取字节并将其解码为字符

套接InputStream类型流

2.OutputStreamReader类:可使用指定的字符集将要写入流中的字符编码

套接OutputStream类型流

3.常用方法:String getEncoding()

九、数据流

1.DataInputStream类:允许应用程序以与机器无关方式从底层输入流中读取基本Java数据类型

(1)套接InputStream类型流

(2)常用方法:数据类型 read数据类型()

2.DataOutputStream类:应用程序以适当方式将基本Java数据类型写入输出流中

(1)套接OutputStream类型流

(2)常用方法:数据类型 write数据类型()

十、打印流

1.打印流:属于输出流,方便地打印各种数据值的表示形式

(1)提供了print()、println()方法的多种重载形式

(2)不会抛出异常,用户通过检测错误状态获取错误信息

(3)有自动刷新功能,自动调用flush()方法

(4)套接OutputStream类型流

2.PrintStream类:针对字节操作的输出流

打印字符时适用平台默认字符编码

3.PrintWriter类:针对字符操作的输出流

十一、对象流

1.java.io.Serializable接口:实现此接口启用其序列化功能

2.transient关键字:用此关键字修饰的成员变量不被序列化

3.ObjectInputStream类:可以为应用程序提供对对象图形的持久存储,对以前使用ObjectOutputStream写入的基本数据和对象进行反序列化

(1)套接InputStream类型流

(2)常用方法:

              int available()

              int skipBytes(int len)

public class ObjectInputStreamTest {
    public static void main(String[] args) {
        FileInputStream fis = null;//文件输入流
        ObjectInputStream ois = null;//文件输出流
        try {
            fis = new FileInputStream("src/com/haina365/lesson19/Student.txt");
            ois = new ObjectInputStream(fis);
            //读取文件中的对象,一次获取一个对象,同时读取到的对象都是Object类型的
            Student s1 = (Student) ois.readObject();
            System.out.println(s1);
            Student s2 = (Student) ois.readObject();
            System.out.println(s2);
            Student s3 = (Student) ois.readObject();
            System.out.println(s3);
            Student s4 = (Student) ois.readObject();
            System.out.println(s4);
            //以EOFEException异常作为文件读取结束的标志
        } catch (EOFException e) {
            System.out.println("文件读取结束");
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                //先关闭最外层的处理流再关里面的节点流
                if (ois != null) {
                    ois.close();
                }
                //如果代码中既有输入流还有输出流,那么关闭的时候输入输出流谁先可以谁会都可以
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

        }
    }
}

4.ObjectOutputStream类:将Java对象的基本数据类型和图形写入OutputStream,只能将支持java.io.Serializable接口的对象写入流中

套接OutputStream类型流

public class ObjectOutputStreamTest {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        try {
            fos = new FileOutputStream
                    ("src/com/haina365/lesson19/Student.txt");
            oos = new ObjectOutputStream(fos);
            Student s1 = new Student(1001,"张三",18);
            Student s2 = new Student(1001,"张三",18);
            Student s3 = new Student(1001,"张三",18);
            oos.writeObject(s1);//往文件中写入对象的写法
            oos.writeObject(s2);
            oos.writeObject(s3);
        }catch (FileNotFoundException e){
            e.printStackTrace();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

5.使用对象流要先开启对象的序列化功能,开启方式是类实现序列化接口(Serializable)
瞬时状态:保存在内存中的数据,其状态为瞬时状态
持久状态:保存在硬盘中的数据,其状态为持久状态
序列化:数据有瞬时状态变成持久状态就是序列化
反序列化:数据由持久化状态变为瞬时状态就是反序列化。

public class Student implements Serializable {
    private int no;
    private String name;
    private int age;
    public Student(int no,String name,int age){
        this.no = no;
        this.name = name;
        this.age = age;

    }

    @Override
    public String toString() {
        return "Student{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值