java基础-----I/O流

I/O流视频

IO流

在这里插入图片描述

1、什么是IO

只要是流都要涉及到关闭流操作

对于任何程序设计语言而言,输入输出(Input/Output)系统都是非常核心的功能。程序运行需要数据,数据的获取往往需要外部系统进行通信,外部系统可能是文件、数据库、其他程序、网络、IO设备等。外部系统比较复杂多变,那么我们有必要通过某种手段进行抽象、屏蔽外部的差异,从而实现更加便捷的编程
输入(Input)指的是:可以让程序从外部系统获得数据(核心含义是“读”,读取外部数据)。	
  • 读取硬盘上的文件内容到程序。例如:播放打开一个视频文件,word打开一个doc文件
  • 读取网络上某个位置内容到程序。例如:浏览器中输入网址后,打开该网址对应的网页内容,下载网络上某个网址的文件
  • 读取数据库系统的数据到程序
  • 读取某些硬件系统数据到程序

输出(Output)指的是程序输出数据给外部系统,从而可以操作外部系统。含义是“写”

  • 将数据写到硬盘中,例如:我们编辑完一个word文档后,将内容写到硬盘上进行保存
  • 将数据写到数据库系统中。例如:我们注册一个网站会员,实际就是后台程序向数据库中写入一条记录。
  • 将数据写到某些硬件系统中。例如:导弹系统导航程序将新的路径输出到飞控子系统,飞控子系统根据数据修正飞行路径。

2、数据源

 数据源Data Source,提供数据的原始媒介,常见的数据源有:数据库、文件、其他程序、内存、网络连接、IO设备。

数据源分为:源设备、目标设备。

  • 源设备:为程序提供数据,一般对应输入流
  • 目标设备:程序数据的目的地,一般对应输出流

3、流

输入/输出流的划分是相对程序而言的,并不是相对数据源。

4、java中四大IO抽象类

InputStream/OutputStream和Reader/Writer类是所有IO流的抽像父类
InputStream:此抽象类是表示字节输入流的所有父类,InputStream是一个抽象类,它不可以实例化,数据的读取需要由它的子类来实现,跟具节点的不同,它派生了不同的节点流子类。继承自InputStream的流都是用于向程序中输入数据,且数据的单位为字节(8bit)
int read():读取一个字节的数据,并将字节的值作为int类型返回(0-255之间)如果未读出字节则返回-1(返回值为-1表示读取结束)
void close():关闭输入流对象,释放相关系统资源。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5、java中流的概念细分

按流的方向分类:
输入流:数据流从数据源到程序(InputStream、Reader结尾的流)
输出流:数据流从程序到目的地(OutputStream、Writer结尾的流)

按照处理的数据单元分类:
字节流:以字节为单位获取数据、命名上以Stream结尾的流一般是字节流
字符流:以字符为单位获取数据,命名以Reader/Writer结尾的流一般是字符

按照处理对象不同分类:
节点流:可以直接从数据或目的地读写数据,如FileInputStream,FileReader、DataInputStream
处理流:不直接连接到数据源或目得地,是处理流得流,通过对其他流得处理提高程序的性能。如BufferedlnputStream、BufferedReader等,处理流也叫包装流
在这里插入图片描述
java中IO流的体系分类P334

IO案例
读取文件中的字符

public class FirstIODemo {
    public static void main(String[] args) {
        //选择一个流对象,数据源是个文件,是输入流,所以算则FileInputStream
        //在用IO流时时会经常出现编译错误,这就要求我们使用try-catch,捕获异常
        FileInputStream fis = null;
        try{
            //创建字节输入流对象
            fis = new FileInputStream("G:/java基础/a.txt");
            //read返回的是整数型,一次只读取一个字符
            int s1 = fis.read();
            int s2 = fis.read();
            int s3 = fis.read();
            int s4 = fis.read(); //文件内容已读取完毕,则返回-1
            //read()读取文件第一个字符,将字符转换为对应的十进制
            System.out.println(s1); //97
            System.out.println(s2); //98
            System.out.println(s3); //99
            System.out.println(s4); //-1

        }catch (Exception e){

        }finally {
            if(fis !=null){
                try{
                    fis.close();
                }catch (Exception e){
                }
            }
        }
    }
}
//还可以用循环输出文件里的内容
import java.io.FileInputStream;

public class SeconIODemo {
    public static void main(String[] args) {
        FileInputStream fis = null;
        try{
            //创建字节输入流对象
            fis = new FileInputStream("G:/java基础/a.txt");
            //利用循环
            StringBuffer sb = new StringBuffer();
            int temp = 0;
            while((temp=fis.read()) != -1){
                System.out.println(temp);
                sb.append((char)temp);
            }
            System.out.println(sb);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

File类的使用

File类的作用
File类是java提供的针对磁盘中的文件或目录转换对象的包装类。一个File对象可以代表一个文件或目录,FIle对象可以实现获取文件和目录属性等功能,可以实现对文件和目录的创建、删除等功能。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import java.io.File;
public class DirectoryDemo {
    public static void main(String[] args) {
        //创建File对象
        File file = new File("g:/a/b/c");
        //创建目录
        System.out.println(file.mkdirs());
        //判断目录是否存在 boolean
        System.out.println(file.exists());
        //判断当前目录是否为路径
        System.out.println(file.isDirectory());
        //获取当前目录的父级目录
        System.out.println(file.getParent());
        System.out.println(file.getParentFile().getName());

        //获取根目录下的所有文件和目录
        File file2 = new File("g:/");
        String[] arr = file2.list();
        for(String str:arr){
            System.out.println(str);
        }
        System.out.println("---------------");
        //listFiles返回的是数组,会把文件的文件名和绝对路径返回过去
        File[] arr2 = file2.listFiles();
        for(File str:arr2){
            System.out.println(str);
        }
    }
}

常用流对象

1、文件字节流

FileInputStream通过字节的方式读取文件,适合读取所有类型的文件(图像、视频、文本文件等)Java也提供了FileReader专门读取文本文件
FileOutputStream通过字节的方式写数据到文件中,适合所有类型的文件,java也提供了FileWriter专门写入文本文件
1.1文件字节流的输入与输出
字节流可以处理二进制文件,也可以处理文本文件

import java.io.FileInputStream;
import java.io.FileOutputStream;
//读取图片
public class FileStreamDemo {
    public static void main(String[] args) {

        FileInputStream fis = null;
        //文件字节输出流对象
        FileOutputStream fos = null;
        try{
            //创建文件字节输入流对象
            fis = new FileInputStream("");
            //创建文件输出流对象
            fos = new FileOutputStream("g:/a.jpg");
            int temp = 0;
            while ((temp = fis.read())!=-1){
                System.out.println(temp);
                //一个字节一个字节的写入
                fos.write(temp);
            }
            //将数据从内存中写入到磁盘中。
            fos.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                if (fis != null ){
                    fis.close();
                }
                if(fos !=null){
                    fos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

1.2通过缓冲区提高读写效率
在这里插入图片描述
例子:发200斤大米,不用缓冲区一次只能拿走一粒,耗时久,用缓冲区,一次打包20斤,提高了速率

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

public class FileStreamBuffedDemo {
    public static void main(String[] args) {
        //读取图片
        FileInputStream fis = null;
        //文件字节输出流对象
        FileOutputStream fos = null;
        try{
            //创建文件字节输入流对象
            fis = new FileInputStream("图片路径");
            //创建文件输出流对象
            fos = new FileOutputStream("g:/a.jpg");
            //创建缓冲区,提高读写效率
            byte[] buff = new byte[1024];
            int temp = 0;
            while ((temp = fis.read(buff))!=-1){
                System.out.println(temp);
                fos.write(buff,0,temp);
            }
            //将数据从内存中写入到磁盘中。
            fos.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                if (fis != null ){
                    fis.close();
                }
                if(fos !=null){
                    fos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

在这里插入图片描述
例子:发200斤大米,一次性拿完。

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

public class FileStreamBuffedDemo2 {
    public static void main(String[] args) {
        //读取图片
        FileInputStream fis = null;
        //文件字节输出流对象
        FileOutputStream fos = null;
        try{
            //创建文件字节输入流对象
            fis = new FileInputStream("C:/Users/lenovo/Desktop/文档/四级成绩单.jpg");
            //创建文件输出流对象
            fos = new FileOutputStream("g:/a.jpg");
            //创建缓冲区,提高读写效率,fis.available返回int,返回图片预估大小的值
            byte[] buff = new byte[fis.available()];
            fos.write(buff);
            //将数据从内存中写入到磁盘中。
            fos.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                if (fis != null ){
                    fis.close();
                }
                if(fos !=null){
                    fos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

1.4通过字节缓冲流提高读写效率
在这里插入图片描述

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class FileStreamBuffedDemo3 {
    public static void main(String[] args) throws Exception {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        fis = new FileInputStream("");
        bis = new BufferedInputStream(fis);
        fos = new FileOutputStream("g:/aa.jpg");
        bos = new BufferedOutputStream(fos);
        int temp = 0;
        while((temp = bis.read()) != -1){
            bos.write(temp);
        }
        //将数据从内存中写入到磁盘中。
        bos.flush();
        //关闭顺序:“后开的先关闭”
        if (bis != null){
            bis.close();
        }
        if (fis != null){
            fis.close();
        }
        if (bos != null){
            bos.close();
        }
        if (fos != null){
            fos.close();
        }
    }
}

1.5定义文件拷贝工具类
写个方法用于diaoyongcopy文件,这里复习:static声明的静态方法可以直接用,不用new一个对象

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class FileCopyTools {
    public static void main(String[] args) {
        FileCopyTools f = new FileCopyTools();
        f.copyFile("g:/aa.txt","g:/a/a.txt");
    }
    /*
    * 文件拷贝方法
    * */
    public void copyFile(String src,String src1) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try{
            fis = new FileInputStream(src);
            bis = new BufferedInputStream(fis);
            fos = new FileOutputStream(src1);
            bos = new BufferedOutputStream(fos);
            int temp = 0;
            while((temp = bis.read()) != -1){
                bos.write(temp);
            }
            bos.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                //关闭顺序:“后开的先关闭”
                if (bis != null){
                    bis.close();
                }
                if (fis != null){
                    fis.close();
                }
                if (bos != null){
                    bos.close();
                }
                if (fos != null){
                    fos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

2、 文件字符流

前面介绍的文件字节流可以处理所有的文件,如果我们处理的是文本文件,也可以使用文件字符流,它以字符为单位进行操作。
2.1文件字符输入流

import java.io.FileReader;
public class FileReaderDemo {
    public static void main(String[] args) {
        FileReader frd = null;
        try{
            //创建文件字符输入流对象
            frd = new FileReader("g:/aa.txt");
            //一次读一个字符,返回字符对应的unicode值
            int temp = 0;
            while((temp = frd.read()) != -1){
                System.out.println(temp);
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                if(frd != null){
                    frd.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

2.2文件字符输出流

import java.io.FileWriter;

public class FileWriterDemo {
    public static void main(String[] args) {
        FileWriter fw = null;
        FileWriter fw2 = null;
        try{
            //创建字符输出流对象,如果给定的文件不存在,则FileWriter会自动创建
            fw = new FileWriter("g:/aaa.txt");
            // \r\n为换行回车
            fw.write("你好\r\n");
            //接着用writer直接在原来的字符后面继续追加
            fw.write("你好啊\r\n");
            //将数据从内存中写入到磁盘中
            fw.flush();
            //把原来fw写入的覆盖掉了
            // fw2 = new FileWriter("g:/aaa.txt");
            //这个是增加,不覆盖原来写入的
            fw2 = new FileWriter("g:/aaa.txt", true);
            fw2.write("第二个对象");
            fw2.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(fw != null){
                    fw.close();
                }
                if(fw2 != null){
                    fw2.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

2.3使用字符流实现文本文件的拷贝处理

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

public class FileCopyTools2 {
    public static void main(String[] args) {
        FileReader fr = null;
        FileWriter fw = null;
        try{
            fr = new FileReader("g:/aa.txt");
            fw = new FileWriter("g:/aaa.txt");
            //字符流选用缓冲的数组是char类型,因为操作的是字符流,数组长度只能是固定的
            char[] buffer = new char[1024];
            int temp = 0;
            while((temp = fr.read()) != -1){
                fw.write(buffer,0,temp);
            }
            fw.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                //输入流和输出流先关闭哪个都可以
                if(fr != null){
                    fr.close();
                }
                if (fw != null){
                    fw.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

3、字符缓冲流

BufferedReader/BufferedWriter增加了缓存机制,大大提高了读写文本文件的效率
3.1字符输入缓冲流
BufferedReader是针对输入流的缓冲流对象,提供了更方便的按行读取的方法;readLine();在使用字符流读取文本文件时,我们可以使用该方法以行为单位进行读取

import java.io.BufferedReader;
import java.io.FileReader;

public class BufferdReaderDemo {
    public static void main(String[] args) {
        FileReader fr = null;
        BufferedReader br = null;
        try {
            fr = new FileReader("g:/aaa.txt");
            br = new BufferedReader(fr);
            String temp = "";
            //readLine()以一行为为单位读,返回的时String类型
            while ((temp = br.readLine()) != null){
                System.out.println(temp);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(br != null){
                    br.close();
                }
                if(fr != null){
                    fr.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

3.2字符输出缓冲流
BufferedWriter是针对字符字符输出流的缓冲流对象,在字符输出缓冲流可以使用newLine();方法实现换行处理。

import java.io.BufferedWriter;
import java.io.FileWriter;

public class BufferedWriterDemo {
    public static void main(String[] args) {
        FileWriter fw = null;
        BufferedWriter bw = null;
        try {
            fw = new FileWriter("g:/aaa.txt");
            bw = new BufferedWriter(fw);
            bw.write("asd");
            bw.write("nihao");
            bw.newLine();
            bw.write("ds");
            //刷新
            bw.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (bw != null){
                    bw.close();
                }
                if (fw != null){
                    fw.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

3.3通过字符缓冲流实现文本文件的拷贝

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;

public class FileCopyTools3 {
    public static void main(String[] args) {
            copyFile("g:/aa.txt","g:/aaaa.txt");
    }
    public static void copyFile(String str,String str1){
        FileReader fr = null;
        BufferedReader br = null;
        FileWriter fw = null;
        BufferedWriter bw = null;
        try{

            fr = new FileReader(str);
            br = new BufferedReader(fr);
            String temp = "";
            fw = new FileWriter(str1);
            bw = new BufferedWriter(fw);
            while ((temp = br.readLine())!=null){
                bw.write(temp);
                bw.newLine();
            }
            bw.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(br != null){
                    br.close();
                }
                if(fr != null){
                    fr.close();
                }
                if(bw != null){
                    bw.close();
                }
                if(fw != null){
                    fw.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }

        }
    }
}

4、转换流

在这里插入图片描述

5、字符输出流

在java的IO流中专门提供了用于字符输出的流对象PrintWriter、该对象具有自动行刷新缓冲字符输出流,特点是可以按行写出字符串,并且可通过println()方法实现自动换行。

6、字节数组流

ByteArrayInputStream和ByteArrayOutputStream经常用在需要流和数组之间转化的情况!

6.1字节数组输入流
FileInputStream是把文件当作数据源。ByteArrayInputStream则是把内存中的字节数组对象“当做数据源”

import java.io.ByteArrayInputStream;
public class ByteArrayInputDemo {
    public static void main(String[] args) {
        //返回一个byte字节数组
        byte[] arr = "aadddd".getBytes();
        ByteArrayInputStream bis = null;
        StringBuilder sb = new StringBuilder();
        try {
            //该构造方法参数是一个字节数组,这个字节数组就是数据源
            bis = new ByteArrayInputStream(arr);
            int temp = 0;
            while((temp = bis.read()) != -1){
                System.out.println(temp);
                sb.append((char)temp);
            }
            System.out.println(sb.toString());
        }finally {
            try {
                bis.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

7、数据流

    数据流将基本数据类型与字符串类型作为数据源,从而允许程序以与机器无关的方式从底层输入输出流中操作java基本数据类型与字符串类型。

DataInputStream和DataOutputStream提供了可以存取与机器无关的所有java基础类型数据(int、double、String)到程序当中----即不需要对已读取的数据进行类型转换
(基于字节流和字符流将数据存储到文件当中,数据的类型为字节或者字符,没有int和String等类型)
7.1、数据输出流
将数据按照自己的类型输出到为文件当中

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

public class DataOutputDemo {
    public static void main(String[] args) {
        //处理流
        DataOutputStream dos = null;
        try {
             dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("g:/aa.txt")));
             //利用数据输出流写出,这样输出会乱码。
             dos.writeChar('a');
             dos.writeInt(10);
             dos.writeDouble(Math.random());
             dos.writeBoolean(false);
             dos.writeUTF("你好");
             dos.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(dos != null){
                    dos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }

    }
}

7.2数据输入流
读取基于数据输出流的输入到文件当中的数据类型,能够将数据按照原来的数据类型输入到程序当中。

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

public class DataInputDemo {
    public static void main(String[] args) {
        DataInputStream dis = null;
        try {
            dis = new DataInputStream(new BufferedInputStream(new FileInputStream("g:/aa.txt")));
            //读取数据,直接读取,注意:读取的顺序要与写入的一致,否则不能正确读取数据
            System.out.println("char:"+dis.readChar());
            System.out.println("int:"+dis.readInt());
            System.out.println("double:"+dis.readDouble());
            System.out.println("boolean:"+dis.readBoolean());
            System.out.println("String:"+dis.readUTF());

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (dis != null){
                    dis.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

8、对象流

对象的本质是用来组织和存储数据的,对象本身也是数据,那么能不能将对象存储到硬盘上的文件中呢?能不能将对象通过网络传输到另一个电脑呢?我们可以通过序列化和反序列化来实现这些需求。
8.1Java对象的序例化和反序例化
8.1.1序列化和反序列化是什么
当两个进程远程通信时,彼此可以发送各种类型的数据,无论是何种类型的数据,都会以二进制序列的形式在网络上传送,例如:我们可以通过http协议发送字符串信息;我们也可以在网络上直接发送Java对象。发送方需要把这个Java对象转化成字节序列,才能在网上传播,接收方则需要把字节序列在恢复为Java对象才能正常读取。(通俗的说序列化为发送发将发送的java对象 转换成字节放入到发送包叫做序列化,通过网络传播到接收方,接收方在将字节转换成java对象叫做反序列化)
把Java对象转换为字节序列过程称为对象的序列化,把字节序列恢复为Java对象的过程称为对象的反序列化。
序列化作用:
持久化:把对象的字节序列永久的保存到硬盘上,通常存放在一个文件中
网络通信:在网络上传送对象的字节序列。比如:服务器之间的数据通信、对象传递。
ObjectOutputStream和ObjectInputStream为处理流对象
在这里插入图片描述
8.2操作基本数据类型
数据流只能实现对基本数据类型和字符串类型的读写,并不能对java对象进行读写操作(字符串除外),但是在对象流中除了能实现对基本数据类型进行读写操作外,还可以对java对象进行读写操作。
8.2.1对象流写出基本数据类型

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

public class ObjectOutputStreamBasicTypeDemo {
    public static void main(String[] args) {
        //定义对象字节输出流,对基本数据类型进行输出的时候。跟数据流的使用是一样的
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("g:/aa.txt")));
            oos.writeInt(10);
            oos.writeDouble(Math.random());
            oos.writeChar('a');
            oos.writeBoolean(true);
            oos.writeUTF("你好");
            oos.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (oos != null){
                    oos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }

        }
    }
}

8.2.2对象流读取基本数据类型

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

public class ObjectInputStreamBasicTypeDemo {
    public static void main(String[] args) {
        //创建一个对象字节输入流,将数据从文件中读取到程序中
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream("g:/aa.txt")));
            System.out.println("char:"+ois.readChar());
            System.out.println("int:"+ois.readInt());
            System.out.println("double:"+ois.readDouble());
            System.out.println("boolean:"+ois.readBoolean());
            System.out.println("String:"+ois.readUTF());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {

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

8.3操作对象
8.3.1将对象序列化到文件
ObjectOutStream可以将一个内存中的java对象通过序列化的方式写入到磁盘的文件中,被序列化的对象必须要实现Serializable序列化接口,否则会抛出异常
8.3.1.1创建对象
将对象序列化到文件

import java.io.Serializable;
// 创建对象
//Serializable标识接口
public class Users implements Serializable {
    private int userid;
    private String username;
    private int age;
    public Users(int userid, String username, int age) {
        this.userid = userid;
        this.username = username;
        this.age = age;
    }
    public Users(){

    }
    public int getUserid() {
        return userid;
   }

    public void setUserid(int userid) {
        this.userid = userid;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;00
public class ObjectOutStreamObjectTypeDemo {

    public static void main(String[] args) {
        ObjectOutputStream oos = null;
        try{
            //ObjectOutputStream为处理流,所以要选择字节输出流
            oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("g:/aa.txt")));
            Users user = new Users(1,"zz",12);
            oos.writeObject(user);
            oos.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(oos != null){
                    oos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

8.3.2将对象反序列化到内存中

import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class ObjectInputStreamTypeDemo {
    public static void main(String[] args) {
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("g:/aa.txt"));
            //ois.readObject返回Object对象,应强制转换成Users类型
            Users users = (Users)ois.readObject();
            System.out.println(users.getAge()+users.getUsername()+users.getUserid());
            System.out.println(users.getAge()+""+users.getUserid()+users.getUsername());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(ois != null){
                    ois.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

9、随机访问流

RandomAccessFile可以实现两个作用

  1. 实现对一个 文件做读和写的操作
  2. 可以访问文件的任意位置,不像其他流只能按照先后顺序读取,默认方法为从头开始读。

三个重要的方法
构造方法—RandomAccessFile(String name,String mode)name用来确定文件,mode取r(读)或rw(读写),通过mode可以确定流对文件的访问权。
seek(long a)用来定位流对象读写文件的位置,a确定读写位置距离文件开头的字节个数
getFilePointer()获得流当前的读写位置
随机访问流

import java.io.RandomAccessFile;
public class RandomAccessFileDemo {
    public static void main(String[] args) {
        //实例化对象
        RandomAccessFile raf = null;
        try {
            raf = new RandomAccessFile("g:/aa.txt","rw");
            //将若干数据写入到文件当中
            int[] arr = new int[]{10,20,30,40,50,60};
            for(int i=0;i<arr.length;i++){
                raf.writeInt(arr[i]);
            }
            //通过随机访问流通过它指向字节数那个指针,从第5个字节开始读
            raf.seek(4);
            System.out.println(raf.readInt()); //输出20,一个int类型占四个字节。
            // 隔一个读一个数据
            for(int i=0;i<10;i+=2){
                raf.seek(i*4);
                System.out.print(raf.readInt()+"\t");//10,30,50
            }
            System.out.println("----------");

            //在第8个字节插入一个数据45,替换之间数据30
            raf.seek(8);
            raf.writeInt(45);
            for(int i=0;i<10;i+=2){
                raf.seek(i*4);
                System.out.print(raf.readInt()+"\t");//10,45,50
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(raf != null){
                    raf.close();
                }

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

10、File类在IO中的作用

当以文件作为数据源或目标,除了可以使用字符串作为文件以及位置的指定外,我们也可以使用File类指定。
(与前面的字符字节输入流输出流无太大)

import java.io.*;

public class FileInIODemo {
    public static void main(String[] args) {
        //字节输入输出缓冲流
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new FileReader(new File("g:/aaa.txt")));
            bw = new BufferedWriter(new FileWriter(new File("g:/aaaa.txt")));
            String temp = "";
            int i = 0;
            while((temp = br.readLine())!=null){
                bw.write(i+","+temp);
                //换行
                bw.newLine();
                i++;
            }
            bw.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(br != null){
                    br.close();
                }
                if(bw != null){
                    bw.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

第三方IO包-ApacheIO包

下载与添加commoms-io包
1、下载地址
https://commons.apache.org/proper/commons-io/download_io.cgi
2、添加jar包到IDEA
3、FileUtils的使用
cleanDirectory:清空目录内容,但不删除目录
在这里插入图片描述
在这里插入图片描述writerStringToFile:将字符串内容写到文件。

readFileToString的使用


import org.apache.commons.io.FileUtils;
import java.io.File;
public class FileUtilsDemo1 {
    public static void main(String[] args)throws Exception {
        //可以指定编码,没给定按照utf-8
        String content = FileUtils.readFileToString(new File("g:/aaa.txt"));
        System.out.println(content);
    }
}

copyDirectory的使用

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.FileFilter;

public class FileUtilsDemo2 {
    public static void main(String[] args) throws Exception{
        //接口不能被实例化
        FileUtils.copyDirectory(new File("源路径"),new File("目的 路径"), new FileFilter(){
            //在文件拷贝时的过滤条件,符合条件不被过滤
            @Override
            public boolean accept(File pathname){
                if(pathname.isDirectory() || pathname.getName().endsWith("html")){
                    return true;
                }
                return false;
            }
        });
    }
}

4、IOUtils方法的使用
IOUtils方法大部分是重载的
在这里插入图片描述
在这里插入图片描述
write方法:向流里面写入内容
writerLine()方法:向流里面写入一行内容
toString案例

import org.apache.commons.io.IOUtils;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class IOUtilsDemo {
    public static void main(String[] args) throws Exception {
        //不给charsetName赋值默认为utf-8,前提条件文件里放的为字符,读其他乱码
        String content = IOUtils.toString(new FileInputStream("g:/aaa.txt"),"utf-8");
        System.out.println(content);
    }
}

本章节总结

1、按流的方向分类

  • 输入流:数据源到程序(InputStream、Reader读进来)
  • 输出流:程序到目的地(OutPutStream、Writer写出去)

2、按流的处理数据单元分类:

  • 字节流:按照字节读取数据(InputStream、OutputStream)
  • 字符流:按照字符读取数据(Reader、Writer)

3、按流的功能

  • 节点流:可以直接从数据源或目的地读写数据
  • 处理流:不直接连接到数据源或目的地,是处理流的流,通过对其他流的处理,提高程序的性能

4、IO的四个基本抽象类
InputStream,OutputStream,Reader,Writer

5、InputStream的实现类

  • FileInputStream:文件字节输入流
  • ByteArrayInputStream:字节数组的字节输入流
  • BufferedInputStream:字节缓冲输入流
  • DataInputStream:数据字节输入流
  • ObejectInputStream:对象字节输入流

6、OutputStream的实现类

  • FileOutputStream:文件字节输出流
  • ByteArrayOutputStream:字节数组的字节输出流
  • BufferedOutputStream:字节缓冲输出流
  • DataOutputStream:数据字节输出流
  • ObejectOutputStream:对象字节输出流
  • printStream:字节输出流

7、Reader的实现类

  • FileReader:文件字符输入流
  • BufferdReder:文件缓冲字符输入流
  • InputStreamReader:字节转字符的输入流

8、Writer的实现类

  • FileWriterr:文件字符输出流
  • BufferdWriter:文件缓冲字符输出流
  • OutputStreamWriter:字节转字符的输出流

9、把Java对象转换为字节序列的过程称为对象的序列化
10、把字节序列恢复Java对象的过程称为反序列化

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值