IO流---

本文详细介绍了Java中的IO流,包括字节流、字符流的分类和使用,如FileReader、FileWriter、BufferedReader、BufferedWriter等。通过示例代码展示了文件读写、复制以及字符集转换的过程,强调了缓冲流提高读写速度的作用,并提及了对象流的序列化和反序列化。
摘要由CSDN通过智能技术生成

IO流原理及流的分类

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
流按不同的角度分类
在这里插入图片描述
主要关注蓝色框的这些流。
在这里插入图片描述

    一、流的分类:
    1.操作数据单位:字节流、字符流
    2.数据的流向:输入流、输出流
    3.流的角色:节点流、处理流

    二:流的体系结构
    抽象基类         节点流(或文件流)       缓冲流(处理流的一种)
    InputStream     FileInputStream    BufferedInputStream
    OutputStream    FileOutputStream   BufferedOutputStream
    Reader          FileReader         BufferedReader
    Writer          FileWriter         BufferedWriter

字符输入输出流

FileReader读入数据

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class Demo2 {
    public static void main(String[] args){
         /*
        将hello.txt文件内容读入程序中,并输出到控制台
         */
        //1.实例化File类的对象,指明要操作的文件
        File file=new File("D:\\java代码\\src\\src\\com\\java\\hello.txt");
        //2.提供具体的流
        FileReader fr=null;
        try{
            fr=new FileReader(file);
            //3.数据的读入 返回读入的一个字符。如果达到文件末尾,返回-1
//        方式一:
//        int data=fr.read();
//        while (data!=-1){
//            System.out.print((char)data);
//            data=fr.read();
//        }
            //方式二:语法上针对方式一的修改
            int data;
            while ((data=fr.read())!=-1){
                System.out.print((char)data);
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            //4.流的关闭操作
            if (fr!=null){
                try {
                    fr.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

说明:
1.read()的理解:返回读入的一个字符。如果达到文件末尾,返回-1;
2异常的处理:为了保证流资源一定可以执行关闭操作。需要使用try-catch-finlly处理。
3.读入的文件一定要存在,否则报错FileNotFoundException 找不到指定文件。

FileReader中使用read(char[ ] cbuf)
对read()操作升级:使用read的重载方法。
方式一:

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class Demo2 {
    public static void main(String[] args){
         /*
        将hello.txt文件内容读入程序中,并输出到控制台
         */
        //1.实例化File类的对象,指明要操作的文件
        File file=new File("D:\\java代码\\src\\src\\com\\java\\hello.txt");
        //2.提供具体的流
        FileReader fr=null;
        try{
            fr=new FileReader(file);
            char[] cbuf=new char[5];
            int len;
            //read(char[] cbuf):返回每次读入cbuf数组中的字符个数。
            //如果读到文件末尾,返回-1.
            while ((len=fr.read(cbuf))!=-1){
//错误的写法,如果末尾的文件内容比较短,不足数组长度5,那么将无法覆盖整个数组
//那么输出时,上一次输出未被覆盖的内容会再一次输出
//                for(int i=0;i<cbuf.length;i++){
//                    System.out.print(cbuf[i]);
//                }
                //改正:
                for(int i=0;i<len;i++){
                    System.out.print(cbuf[i]);
                }
            }

        }catch (IOException e){
            e.printStackTrace();
        }finally {
            //4.流的关闭操作
            if(fr!=null){
                try {
                    fr.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

方式二:

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class Demo2 {
    public static void main(String[] args){
         /*
        将hello.txt文件内容读入程序中,并输出到控制台
         */
        //1.实例化File类的对象,指明要操作的文件
        File file=new File("D:\\java代码\\src\\src\\com\\java\\hello.txt");
        //2.提供具体的流
        FileReader fr=null;
        try{
            fr=new FileReader(file);
            char[] cbuf=new char[5];
            int len;
            //错误写法,对应之前的i<cbuf.length错误
//            while ((len=fr.read(cbuf))!=-1){
//                String str=new String(cbuf);
//                System.out.print(str);
//            }
            //正确写法
            while ((len=fr.read(cbuf))!=-1){
                String str=new String(cbuf,0,len);
                System.out.print(str);
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            //4.流的关闭操作
            if (fr!=null){
                try {
                    fr.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

FileWriter读出数据

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class Demo2 {
    public static void main(String[] args){
         /*
        从内存中写出数据到硬盘的文件里
        说明:
          输出操作对应的file可以不存在,若不存在,输出的过程中会自动创建此文件。
          FileWriter fw=new FileWriter(file,false)
          表示不在文件原有的内容上叠加读出的内容,删去程序执行前的原有内容重新写
          默认情况是false

          FileWriter fw=new FileWriter(file,true)
          表示在文件原有的内容后面继续写内容
         */
        //1.实例化File类的对象,指明要操作的文件
        File file=new File("D:\\java代码\\src\\src\\com\\java\\hello.txt");
        //2.提供FileWriter的对象,用于数据的写出
        FileWriter fw=null;
        try {
            fw=new FileWriter(file);
            //3.写出的操作
            fw.write("I have a deream\n");
            fw.write("i love u");
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if(fw!=null){
                //4.流资源关闭
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        
    }
}

利用FileReader和FileWriter实现文本文件的复制

import java.io.*;
public class Demo1{
    public static void main(String[] args) {
        //file:原文件,一定要存在
        //file1:复制内容的文件,可以不存在,系统自动创建
        File file=new File("D:\\java代码\\src\\src\\com\\java\\hello.txt");
        File file1=new File("D:\\java代码\\src\\src\\com\\java\\hello1.txt");
        FileReader fr=null;
        FileWriter fw=null;
        try{
            fw=new FileWriter(file1);
            fr=new FileReader(file);
            char[] cbuf=new char[10];
            int len;
            while ((len=fr.read(cbuf))!=-1){
                fw.write(sbuf,0,len);
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if(fr!=null){
                try {
                    fr.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
            if(fw!=null){
                try {
                    fw.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

字符流不能处理图片文件
在这里插入图片描述

字节输入输出流

FileInputStream和FileOutputStream不能处理文字文件(但是复制操作可以),可能会乱码,但是数字和字母可以。
而字符流不能用于复制非文本文件。

复制图片:

import java.io.*;
public class Demo1{
    public static void main(String[] args) {
        File file=new File("D:\\大一下学期文档\\桌面壁纸.jpg");
        File file1=new File("D:\\大一下学期文档\\ok.jpg");
        FileInputStream fr=null;
        FileOutputStream fw=null;
        try{
            fw=new FileOutputStream(file1);
            fr=new FileInputStream(file);
            byte[] buffer=new byte[1024];
            int len;
            while ((len=fr.read(buffer))!=-1){
                fw.write(buffer,0,len);
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if(fr!=null){
                try {
                    fr.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
            if(fw!=null){
                try {
                    fw.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

结论: 对于文本文件(.txt,.java,.c,.cpp),使用字符流处理。对于非文本文件(.jpg,.map3,.mp4,.avi,.doc,.ppt,…),使用字节流处理。

使用缓冲流(字节型)对非文本文件的复制
BufferedInputStream
BufferedOutputStream
缓存流的作用:提高流的读取、写入的速度
提高的原因:内部提供了一个缓冲区。

import java.io.*;
public class Demo1{
    public static void main(String[] args) {
        /*
        处理流之一:缓冲流的使用
        1.缓冲流:
        BufferedInputStream
        BufferedOutputStream
        BufferedReader
        BufferedWriter
        2.作用:提供流的读取、写入的速度
         */
        //实现非文本文件的复制
        //1.造文件
        File srcfile=new File("D:\\大一下学期文档\\桌面壁纸.jpg");
        File desfile=new File("D:\\大一下学期文档\\ok.jpg");

        //2.造节点流
        FileInputStream fis=null;
        FileOutputStream fos=null;
        //3.造缓冲流
        BufferedInputStream bis=null;
        BufferedOutputStream bos=null;
        try {
            fis=new FileInputStream(srcfile);
            fos=new FileOutputStream(desfile);

            bis=new BufferedInputStream(fis);
            bos=new BufferedOutputStream(fos);
            //复制细节:读取+写入
            byte[] buffer=new byte[10];
            int len;
            while ((len=bis.read(buffer))!=-1){
                bos.write(buffer,0,len);
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            /*4.资源关闭:先关外层再内层
            造流的时候先造内层再外层
            说明:关闭外层流的同时,内层流也会自动地关闭。
            所以关于内层流的关闭可以省略
            */
            try {
                if(bis!=null)
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(bos!=null)
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

使用缓冲流(字符型)对文本文件复制
BufferedWriter
BufferedReader
处理流就是“套接”在已有流的基础上的。
和之前字节型的缓冲流类似,不过相对于字节流,多了一个读取方法。
在这里插入图片描述

处理流之二:转换流

在这里插入图片描述

    处理流之二:转换流的使用:将一个字节的输入流转换为字符的输入流
    1.转换流:
       InputStreamReader
       OutputStreamWriter
    2.作用:提供字节流与字符流之间的转换
    3.解码:字节、字节数组--->字符数组、字符串
      编码:字符数组、字符串--->字节、字节数组
    4.字符集

解码

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class Demo {
    public static void main(String[] args) {
        FileInputStream fis=null;
        InputStreamReader isr=null;
        try {
            fis=new FileInputStream("D:\\java代码\\src\\src\\com\\java\\hello.txt");
            //参数2:指明字符集,字符集的种类取决于hello.txt文件存储时按照什么字符集
            isr=new InputStreamReader(fis,"UTF-8");
            char[] cbuf=new char[20];
            int len;
            while ((len=isr.read(cbuf))!=-1){
                String str=new String(cbuf,0,len);
                System.out.println(str);
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                if(isr!=null)
                isr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

编码

import java.io.*;

public class Demo {
    public static void main(String[] args) {
        File file=new File("D:\\java代码\\src\\src\\com\\java\\hello.txt");
        File file1=new File("D:\\java代码\\src\\src\\com\\java\\hello1.txt");
        FileInputStream fis=null;
        FileOutputStream fos=null;
        InputStreamReader isr=null;
        OutputStreamWriter osw=null;
        try {
            fis=new FileInputStream(file);
            fos=new FileOutputStream(file1);
            isr=new InputStreamReader(fis,"UTF-8");
            osw=new OutputStreamWriter(fos,"gbk");
            char[] cbuf=new char[20];
            int len;
            while ((len=isr.read(cbuf))!=-1){
                osw.write(cbuf,0,len);
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                if(isr!=null)
                isr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(osw!=null)
                osw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

字符集
在这里插入图片描述

标准输入、输出流

该部分内容只需要稍作了解
在这里插入图片描述

对象流

在这里插入图片描述
对象序列化机制
在这里插入图片描述

import java.io.*;

public class Demo {
    public static void main(String[] args) {
        /*
        对象流的使用
        1.ObjectInputStream和ObjectOutputStream
        2.作用:用于存储和读取基本数据类型数据或对象的处理流。
          它的强大之处就是可以把java中的对象写入到数据源中,
          也能把对象从数据源中还原回来。
        */
        //序列化过程:将内存中的java对象保存到磁盘中或通过网络传输出去。
        //使用ObjectOutputStream实现
        ObjectOutputStream oos= null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("hello.dat"));
            oos.writeObject(new String("i love beijing"));
            oos.flush();//刷新操作
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(oos!=null)
                oos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        //反序列化过程:将磁盘文件中的对象还原为内存中的一个java对象
        //使用OnjectInputStream来实现
        ObjectInputStream ois= null;
        try {
            ois = new ObjectInputStream(new FileInputStream("hello.dat"));
            Object obj= null;
            obj = ois.readObject();
            String str=(String)obj;
        } catch (IOException e) {
            e.printStackTrace();
        }catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                if(ois!=null)
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

java对象可序列化需要满足的要求
在这里插入图片描述
需要当前类提供一个全局常量:serialVersionUID
自定义Person类:

import java.io.*;

public class Demo {
    public static void main(String[] args) {
        ObjectOutputStream oos=null;
        try {
            oos=new ObjectOutputStream(new FileOutputStream("object.dat"));
            oos.writeObject(new Person("11",12));
            oos.flush();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                if (oos!=null)
                oos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        ObjectInputStream ois=null;
        try {
            ois=new ObjectInputStream(new FileInputStream("object.dat"));
            Person p=(Person) ois.readObject();
            System.out.println(p);
        }catch (IOException e){
            e.printStackTrace();
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }catch (ClassCastException e){
            e.printStackTrace();
        }finally{
            try {
                if(ois!=null)
                    ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

class Person implements Serializable{
    public static final long serialVersionUID=475463534532L;

    private String name;
    private int age;

    public  Person(String name,int age){
        this.name=name;
        this.age=age;
    }
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

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

在这里插入图片描述
ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量。

随机存取文件流

在这里插入图片描述
在这里插入图片描述
p616-619跳过先不看

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值