IO流学习笔记(一)

IO流

体系图 :

  • 版本1

在这里插入图片描述

  • 版本2

在这里插入图片描述
在这里插入图片描述

一、概述

1.1、什么是IO

生活中,你肯定经历过这样的场景。当你编辑一个文本文件,忘记了ctrl+s.,可能文件就白白编辑了。当你电脑上插入一个U盘,可以把一个视频,拷贝到你的电脑硬盘里。那么数据都是在哪些设备上的呢?键盘内存、硬盘、外接设备等等。

我们把这种数据的传输,可以看做是一种数据的流动,按照流动的方向,以内存为基准,分为输入input和输出output,即流向内存是输入流,流出内存的输出流。

Java中I/O操作主要是指使用 java.io 包下的内容,进行输入、输出操作。输入也叫做读取数据,输出也叫做作写出数据。

1.2、IO的分类

根据数据的流向分为 : 输入流 和 输出流。

  • 输入流︰把数据从其他设备上读取到内存中的流。
  • 输出流:把数据从内存中写出到其他设备上的流。

根据数据的类型分为 : 字节流 和 字符流。

在这里插入图片描述

二、字节流

2.1、一切皆为字节

一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都一个一个的字节,那么传输时一样如此。所以,字节流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据。

2.2、OutputStream 类

java.io.outputStream 抽象类 是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。它定义了字节输出流的基本共性功能方法。

  • public void close( )︰关闭此输出流并释放与此流相关联的任何系统资源。
  • public void flush( )︰刷新此输出流并强制任何缓冲的输出字节被写出。
  • public void write( byte[ ] b ):将b.length字节从指定的字节数组写入此输出流。
  • public void write( byte[ ] b, int off,int len )︰从指定的字节数组写入len字节,从偏移量off开始输出到此输出流。
  • public abstract void write( int b )∶将指定的字节输出流。

2.3、FileOutputStream 文件字节输出流

java.io.FileOutputStream extends outputstream 文件字节输出流

作用 : 把内存中的数据写入到硬盘的文件中

构造方法:

//创建一个向具有指定名称的文件中写入数据的输出文件流。
FileoutputStream(String name,[boolean append])
//创建一个向指定File对象表示的文件中写入数据的文件输出流。
FileoutputStream(File file, [boolean append] )

参数:写入数据的目的地

string name : 目的地是一个文件的路径

File file : 目的地是一个文件

append : 追加写开关

true:创建对象不会覆盖源文件,继续在文件的末尾追加写数据

false:创建一个新文件,覆盖源文件

构造方法的作用:

1.创建一个FileOutputstream对象

2.会根据构造方法中传递的文件/文件路径,创建一个空的文件

3.会把FiLeoutputstream对象指向创建好的文件

写入数据的原理(内存–>硬盘)

java程序–>JVM(java虚拟机)–>OS(操作系统)–>os调用写数据的方法–>把数据写入到文件中

字节输出流的使用步骤(重点):

1.创建一个Fileoutputstream莉象,构造方法中传递写入数据的目的地

2.调用FiLeoutputstream对象中的方法write( ),把数据写入到文件中

3.释放资源(流使用会占用一定的内存,使用完毕要把内存清空,提供程序的效率)

例子:

public class FileOutputStreamTest {
    
    private static FileOutputStream fos = null;
    public static void main(String[] args) throws IOException {
        //使用 File 对象的方式
        File file = new File("C:\\Users\\LOL\\Desktop\\test.txt");
        fos = new FileOutputStream(file);
        //使用路径的方式
        fos = new FileOutputStream("C:\\Users\\LOL\\Desktop\\test.txt");
        fos.write("我喜欢你,但你不知道。".getBytes());
        fos.close();
    }
}

内存分析:

在这里插入图片描述

2.4、lnputStream 类

java.io.InputStream 抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。它定义

了字节输入流的基本共性功能方法。

public void close( ) //关闭此输入流并释放与此流相关联的任何系统资源。
public abstract int read( ) // 从输入流读取数据的下一个字节。读取到文件的末尾返回 `-1`。
// 从该输入流读取最多  b.length` 个字节的数据作为字节数组。读取到文件的末尾返回 -1。
read(byte[ ] b) : 
public int read(byte[ ] b)//从输入流中读取一些字节数,并将它们存储到字节数组b中

小贴士 :

close方法,当完成流的操作时,必须调用此方法,释放系统资源。

2.5 FilelnputStream 文件字节输入流类

java.io.FileInputstream类是文件字节输入流,从文件中读取字节。

构造方法:

  • FileInputStream(File file) : 通过打开与实际文件的连接来创建一个FilelnputStream ,该文件由文件系统中的File对象 file 命名。
  • FileInputStream(String name ) : 通过打开与实际文件的连接来创建一个FilelnputStream,该文件由文件系统中的路径名 name 命名。

例子:

public static void main(String[] args) throws IOException {
        //使用 File 对象的方式
        File file = new File("G:\\JavaCode\\IOTest\\test.txt");
        FileInputStream fis = new FileInputStream(file);
        int len = 0;
        //读一个字节
        len = fis.read();
        System.out.println("我是len单个字节:"+len);
        //读多个字节--管道流(便于输出,它重写了toString()方法)
        len = 0;
        ByteArrayOutputStream baoos = new ByteArrayOutputStream();
        byte[] buffer = new byte[10];
        while ((len=fis.read(buffer))!=-1){
            baoos.write(buffer,0,len);
        }
        System.out.println(baoos.toString());
        baoos.close();
        fis.close();
    }

内存分析:

在这里插入图片描述

  1. 方法的参数byte[]的作用?
    • 起到缓冲作用,存储每次读取到的多个字节
    • 数组的长度一般定义为1024(1kb)或者1024的整数倍
  2. 方法的返回值int是什么?
    • 每次读取的有效字节个数

在这里插入图片描述

三、字符流

当使用字节流读取文本文件时,可能会有一个小问题。就是遇到中文字符时,可能不会显示完整的字符,那是因为一个中文字符可能占用多个字节存储。所以Java提供一些字符流类,以字符为单位读写数据,专门用于处理文本文件。

3.1 Reader 类

java.io.Reader 抽象类是表示用于读取字符流的所有类的超类,可以读取字符信息到内存中。它定义了字

符输入流的基本共性功能方法。

public void close()//关闭此流并释放与此流相关联的任何系统资源。
public int read()//从输入流读取一个字符。
public int read(char[] cbuf)//从输入流中读取一些字符,并将它们存储到字符数组cbuf中。

3.2 FileReader 文件字符输入流

java.io.FileReader类是读取字符文件的常用类。构造时使用系统默认的字符编码和默认字节缓冲区。

java.io.FileReader extends InputstreamReader extends ReaderFileReader : 文件字符输入流

作用 : 把硬盘文件中的数据以字符的方式读取到内存中

构造方法:

  • FileReader( String fiLeName)
  • FileReader(File file)

参数:读取文件的数据源

  • string fiLeName:文件的路径
  • File file:一个文件

FileReader构造方法的作用 :

1.创建一个FileReader对象

2.会把FileReader对象指向要读取的文件

字符输入流的使用步骤:

1.创建FiLeReader对象,构造方法中绑定要读取的数据源

2.使用FiLeReader对象中的read( )方法读取文件

3.释放资源

例子:

public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("G:\\JavaCode\\IOTest\\test.txt");
        int len = 0;
        //一次读取一个字符
        len = fr.read();
        System.out.println();

        //一次读取多个字符
        len = 0;
        char[] cbuffer = new char[20];
        while ((len = fr.read(cbuffer))!=-1){
            System.out.println(new String(cbuffer,0,len));
        }
        fr.close();

3.3 Writer 类

java.io.writer 抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。它定义了字节输出流的基本共性功能方法。

void write(int c)//写入单个字符。
void write(char[] cbuf)//写入字符数组。
//写入字符数组的某一部分,off数组的开始索引len写的字符个数
abstract void write(char[ ] cbuf,int off, int len)
void write(String str)//写入字符串。
//写入字符串的某一部分,off字符串的开始索引,len写的字符个数。
void write(String str,int off, int len)
void flush()//刷新该流的缓冲。
void close()//关闭此流,但要先刷新它。

3.4 FileWriter 文件字符输出流

java.io.FiLewriter extends outputStreamlvriter extends lwriter Filewriter:文件字符输出流

java.io.Filewriter类是写出字符到文件的常用子类。构造时使用系统默认的字符编码和默认字节缓冲区。

作用:把内存中字符数据写入到文件中

构造方法:

Filewriter(File file,[boolean append]) 根据给定的File 对象构造一个 Filewriter 对象。

Filewriter(String fileName,[boolean append])根据给定的文件名构造一个FiLewriter对象。

参数 : 写入数据的目的地

string fiLeName:文件的路径

File file:是一个文件

append : 追加写开关

true:创建对象不会覆盖源文件,继续在文件的末尾追加写数据

false:创建一个新文件,覆盖源文件

构造方法的作用:

1.会创建一个FileWriter对象

2.会根据构造方法中传递的文件/文件的路径,创建文件

3.会把FileWriter对象指向创建好的文件

字符输出流的使用步骤(重点):

1,创建FileWriter对象,构造方法中绑定要写入数据的目的地。

2.使用FileWriter中的write( )方法,把数据写入到内存缓冲区中(字符转换为字节的过程)

3.使用FileWriter中的flush( )方法,把内存缓冲区中的数据,刷新到文件中

4.释放资源(会先把内存缓冲区中的数据刷新到文件中)

例子:

   public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("G:\\JavaCode\\IOTest\\test.txt",false);
        //写一个字符
        fw.write("\r\n爱");
        //写入多个字符 -- 字符数组形式
        char[] chars = new char[15];
        int len = 0;
        chars = "\r\n文件字符输出流练习,字符数组形式!".toCharArray();
        fw.write(chars);
        fw.write("\r\n");
        fw.write(chars,1,3);//从下标1开始,写三个
        //写入多个字符 -- 字符串形式
        fw.write("\r\n文件字符输出流练习,字符串形式!");
        fw.write("\r\n");
        fw.write("\r\n文件字符输出流练习,字符串形式!",5,3);//从下标1开始,写三个
        fw.close();
    }

四、流的异常处理

4.1、JDK7的新特性

在 try 的后边可以增加一个( ),在括号中可以定义流对象那么这个流对象的作用域就在try中有效,try中的代码执行完毕,会自动把流对象释放,不用写finally。

格式:

try(定义流对象;定义流对象....){
		可能会产出异常的代码
	}catch(异常类变量变量名){
		异常的处理逻辑
}

4.2、JDK9新特性

try的前边可以定义流对象,在try后边的()中可以直接引入流对象的名称(变量名),在try代码执行完毕之后,流对象也可以释放掉,不用写finally。

格式:

A a = new A();
B b = new B();
try(a,b){
		可能会产出异常的代码
	}catch(异常类变量变量名){
	异常的处理迓辑
}

五、缓冲流

1.1、概述

缓冲流,也叫高效流,是对4个基本的Filexxx流的增强,所以也是4个流。

按照数据类型分类 :

  • 字节缓冲流:BufferedInputStream , BufferedOutputstream
  • 字符缓冲流: BufferedReader, Bufferedwriter

缓冲流的基本原理 :

是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统
IO次数,从而提高读写的效率。

1.2、字节缓冲流

构造方法 :

public BufferedInputStream(InputStream in,[int size])//创建一个新的缓冲输入流。
public BufferedoutputStream(outputStream out,[int size])//创建一个新的缓冲输出流。

java.io.BufferedOutputstream extends Outputstream, Bufferedoutputstream : 字节缓冲输出流

继承自父类的共性成员方法 :

  • public void close( ) ︰关闭此输出流并释放与此流相关联的任何系统资源。
  • public void flush( ) :刷新此输出流并强制任何缓冲的输出字节被写出。
  • public void write(byte[ ] b) : 将b.Length字节从指定的字节数组写入此输出流。
  • public void write(byte[ ] b, int off, int Len) : 从指定的字节数组写入len字节,从偏移量off开始输出到此输出流。
  • public abstract void write(int b) : 将指定的字节输出流。

构造方法 :

//创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
BufferedOutputStream(OutputStream out)
//创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输
BufferedOutputStream( outputstream out, int size)

参数 :

  • outputstream out : 字节输出流
    • 我们可以传递FileOutputStream ,缓冲流会给FileOutputStream增加一个缓冲区,提高FiLeOutputStream的写入效率
  • int size : 指定缓冲流内部缓冲区的大小,不指定默认。默认为 8192 (jdk1.8)。

使用步骤(重点) :

  1. 创建FileoutputStream对象,构造方法中绑定要输出的目的地
  2. 创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象,提高FiLeOutputStream对象的效率
  3. 使用BufferedoutputStream对象中的write( )方法,把数据写入到内部缓冲区中
  4. 使用BufferedoutputStream对象中的flush( )方法,把内部缓冲区中的数据,刷新到文件中
  5. 释放资源(会先调用flush( )方法刷新数据)

提示 :

BufferedOutputStream( outputstream out, int size) 构造时填入 size参数和不填写,但在read()中添加参数数组是等价的。

例子 :

public class ImgCopyTest {
    public static void main(String[] args) throws IOException {
        String Suri = "H:\\girl.jpg";
        String Turi = "G:\\JavaCode\\IOTest\\girl.jpg";
        System.out.println("CopyByFio方法耗时:"+CopyByFio(Suri, Turi)+"毫秒");
        System.out.println("CopyByBFio方法耗时:" + CopyByBFio(Suri, Turi )+"毫秒");
    }

    static double CopyByFio(String Suri,String Turi) throws IOException {
        long begin = System.currentTimeMillis();
        FileInputStream fis = new FileInputStream(Suri);
        FileOutputStream fos = new FileOutputStream(Turi);
        int len = 0;
        byte[] buffer = new byte[1024];
        //一次读取一个字节
//        while ((len = fis.read())!=-1){
//            fos.write(len);
//        }
        //使用缓冲区
        while ((len = fis.read(buffer))!=-1){
            fos.write(buffer,0,len);
        }
        fos.close();
        fis.close();
        long end = System.currentTimeMillis();
        return end-begin;
    }


    static double CopyByBFio(String Suri,String Turi) throws IOException {
        long begin = System.currentTimeMillis();
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(Suri));
        BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(Turi));
        int len = 0;
        byte[] buffer = new byte[8192];
        //不使用缓冲区
//        while ((len=bis.read())!=-1){
//            bos.write(len);
//        }
        //使用缓冲区
        while ((len=bis.read(buffer))!=-1){
            bos.write(buffer,0,len);
        }

        bos.close();
        bis.close();
        long end = System.currentTimeMillis();
        return end-begin;
    }
}

1.3字符缓冲流

构造方法 :

public BufferedReader(Reader in)//创建一个新的缓冲输入流。 
public Bufferedwriter(writer out)//创建一个新的缓冲输出流。

构造举例,代码如下︰

//创建字符缓冲输入流
BufferedReader br = new BufferedReader(new FileReader( "br.txt"));
//创建字符缓冲输出流
Bufferedwriter bw = new Bufferedwriter(new Filewriter( "bw.txt"));

特有方法 :

字符缓冲流的基本方法与普通字符流调用方式一致,不再阐述,我们来看它们具备的特有方法。

BufferedReader : public string readLine()//读一行文字。
行的终止符号:通过下列字符之一即可认为某行已终止:换行('\n ')、回车('\r')或回车后直接跟着换(\r\n)。
返回值:  包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回null  
    
BufferedWriter : public void newLine()//写一行 行分隔符,由系统属性定义符号。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值