JavaSE基础九----<IO流 >流的体系和分类,字节流,字节缓冲流

Posted 小智RE0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaSE基础九----<IO流 >流的体系和分类,字节流,字节缓冲流相关的知识,希望对你有一定的参考价值。


1.关于流的体系分类


1.1输入和输出


输入(input):把电脑硬盘上的文件(数据)读到程序中;进行数据的read操作.

输出(output):从程序向外部设备写入数据,即数据的write操作.

输入和输出都是相对于程序的操作.


1.2输入流和输出流


按数据的传输方向分为:输入流,输出流.
输入流:从程序中读取;
输出流:从程序向外写入.


1.3字节流和字符流


按流的数据单位(编码格式)分为:字节流,字符流.

字节流:以字节为单位. 所有以Stream结尾的类.(可以读写二进制文件,主要处理音频、图片、歌曲、字节流,处理单元为1个字节。)

字符流:以字符为单位,所有以Reader和Writer结尾的类.(主要处理字符或字符串,只能读取纯文本文件,字符流处理单元为1个字符。字节流将读取到的字节数据,去指定的编码表中获取对应文字)

  • InputStream和OutputStream的子类都是字节流;
  • Reader和Writer的子类都是字符流.

1.4节点流和处理流


按封装类型(功能)不同流分为节点流,处理流.

节点流:如果流封装的是某种特定的数据源,如文件、字符串、字符串数组等,则称为节点流。

处理流:如果流封装的是其它流对象,称为处理流。处理流提供了缓冲功能,提高读写效率,同时增加了一些新的方法。



2.字节流


java.io.InputStream ;这个类直接继承Object类;它是输入字节流的所有类的超类.
java.io.OutputStream;也是直接继承Object类;它是字节输出流的所有类的超类。 输出流接收输出字节并将其发送到某个接收器。


字节流中常用类
字节输入流 FileInputStream
字节输出流 FileOutputStream


字节输入流 FileInputStream与字节输出流 FileOutputStream


构造方法


FileInputStream构造方法

常用的有两种

构造方法注释
FileInputStream(File file)通过打开与实际文件的连接创建一个 FileInputStream 对象,该文件由文件系统中的 File对象 file命名
FileInputStream(String name)通过打开与实际文件的连接来创建一个 FileInputStream 对象,该文件由文件系统中的路径名 name命名

在创建FileInputStream对象时,指定要输入(读取)的文件;文件不存在就会抛出异常.

FileOutputStream构造方法

构造方法注释
FileOutputStream(File file)创建文件输出流以写入由指定的 File对象表示的文件
FileOutputStream(String name)创建文件输出流以指定的名称写入文件

在创建FileOutputStream对象时,指定要输出(写入的)目标文件,若文件不存在则会自动创建.但是文件夹不会自动创建.


简单的读写方法


输入流的读取方法

  • public int read( )
    从该输入流读取一个字节的编码值。每read一次就会读取一个字节;返回它的编码值; 以整数的形式返回(0~255),当读到文件内容末尾时,就返回-1.
    使用时需要抛出异常.

例如:读取这个文件;其中,汉字是以utf-8编码的.

在这里插入图片描述

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Demo02 {
    public static void main(String[] args) {

        try {
            FileInputStream fis=new FileInputStream("F:/JAVAIO流练习使用的文件夹/文本文件.txt");
            int r0=fis.read();
            System.out.println(r0);//读取 a            97
            int r1=fis.read();
            System.out.println(r1);//读取 字 第一个字节  229
            int r2=fis.read();
            System.out.println(r2);//读取 字 第二个字节  173
            int r3=fis.read();
            System.out.println(r3);//读取 字 第三个字节  151
            int r4=fis.read();
            System.out.println(r4);//读取 母 第一个字节  230
            int r5=fis.read();
            System.out.println(r5);//读取 母 第二个字节  175
            int r6=fis.read();
            System.out.println(r6);//读取 母 第三个字节  141
            int r7=fis.read();
            System.out.println(r7);//读取 A            65
            int r8=fis.read();
            System.out.println(r8);//读取到末尾 ,返回   -1
            int r9=fis.read();
            System.out.println(r9);//读取到末尾 ,返回   -1
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
                e.printStackTrace();
        }
    }
}

在输出时使用while循环,就会简便很多.

//可使用while循环读取;
            int r=0;
            while ((r=fis.read())!=(-1)){
                System.out.println(r);
            }

输出流的写入方法

  • public void write(int b)
    将指定的字节(向输出流中写入一个字节数据,该字节数据为参数b的低8位)写入此文件输出流,读取一个字节就会写入一个字节.

输入流和输出流中都有关闭流的方法

  • public void close( )
    关闭此文件输出流并释放与此流相关联的任何系统资源。
    关闭传输通道(流的对象);释放系统资源;

一段简单完整的字节流输入输出:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo03 {
    public static void main(String[] args) {
        FileInputStream fis=null;
        FileOutputStream fos=null;
        try {
            //创建FileInputStream对象时,指定要输入的文件;当文件不存在,会抛异常.
             fis=new FileInputStream("F:/JAVAIO流练习使用的文件夹/文本文件.txt");
            //创建FileOutputStream对象时,指定要输出的目标文件;当文件不存在时;会自动创建输出的目标文件,
             fos=new FileOutputStream("F:/JAVAIO流练习使用的文件夹/写入文本.txt");

            //可使用while循环读取;
            int r=0;//记录每次读到的字节值;
            while ((r=fis.read())!=(-1)){
                System.out.println(r);
                fos.write(r);//向指定的文件输出字节;
            }
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }finally {
            //关闭传输通道(流的对象);释放系统资源;
                try {
                    if(fis!=null)
                    fis.close();
                    if(fos!=null)
                        fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
}

在关闭流之后才可进行文件的删除操作.
在日常练习中,在抛出异常时;可以选择声明异常;但是实际的项目中是不允许此类处理方法的.


高效读写


输入流的读取方法

  • public int read( byte[ ] b)
    该方法每次从输入流中读取一个byte数组的长度个字节;返回的是数组中实际传入的内容个数;当读取结束时返回值为-1;

输出流的写入方法

  • public void write(byte[ ] b,int off,int len)
    向外输出一个byte数组个字节,从数组的指定位置开始;写入指定长度的内容.

例如:将一个含有16字节内容的文本文件写入到一个空的文本文件中.

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo04 {
    //练习使用,仅声明异常;
    public static void main(String[] args) throws IOException {
        //创建FileInputStream对象;
        FileInputStream fis=new FileInputStream("F:/JAVAIO流练习使用的文件夹/字节流练习文档1.txt");
        //创建FileOutputStream对象;
        FileOutputStream fos=new FileOutputStream("F:/JAVAIO流练习使用的文件夹/字节流练习文档2.txt");
        //创建一个长度为10的byte数组;相当于一个缓冲区;
        byte[] bytes=new byte[10];
        int length=0;
        //该方法每次从输入流中读取一个byte数组的长度个字节;返回的是数组中实际传入的内容个数;当读取结束时返回值为-1;
        while((length=fis.read(bytes))!=-1){
            //向外输出一个byte数组个字节,从数组的指定位置开始;写入length个的内容.
            fos.write(bytes,0,length);
        }
        //关闭流;
        fis.close();
        fos.close();
    }
}


3.字节缓冲流


按着流的封装类型分为节点流和处理流.
上面的字节流也是一种节点流.
而处理流封装的是其他流的对象.
那么封装字节流对象的即为字节缓冲流.

字节缓冲流:不是直接对文件进行读取或写入,仅仅是包装节点流,提供额外的缓冲功能.

常用类:

缓冲字节输入流 BufferedInputStream.
缓冲字节输出流 BufferedOutputStream.


构造方法

缓冲字节输入流BufferedInputStream

构造方法注释
public BufferedInputStream(InputStream in)创建一个 BufferedInputStream并保存其参数,输入流 in ;默认缓冲区字节长度8192(8KB) ,(private static int DEFAULT_BUFFER_SIZE = 8192;)
public BufferedInputStream(InputStream in,int size)创建 BufferedInputStream;可输入指定size来指定缓冲区大小,并保存其参数,输入流 in

缓冲字节输出流BufferedOutputStream

构造方法注释
public BufferedOutputStream(OutputStream out)创建一个新的缓冲输出流,以将数据写入指定的底层输出流;缓冲区默认长度8192个字节
public BufferedOutputStream(OutputStream out,int size)创建一个新的缓冲输出流,可以指定的缓冲区大小将数据写入指定的底层输出流

//例如:对一个文件的复制粘贴;
import com.sun.istack.internal.NotNull;
import java.io.*;
public class Demo01 {
    public static void main(String[] args) throws IOException {
        //创建节点输入流对象;指定要读取的文件;
        FileInputStream fis=new FileInputStream("F:/鲁大师.exe");
        //创建输入处理流;
        BufferedInputStream bis=new BufferedInputStream(fis);
        //创建节点输出流对象,指定写入的文件;
        FileOutputStream fos=new FileOutputStream("F:/JAVAIO流练习使用的文件夹/鲁大师.exe");
        //创建输出处理流;
        BufferedOutputStream bos=new BufferedOutputStream(fos);

       /* //方式1:效率过慢;
        int r=0;
        //方法public int read();需要一个字节一个字节放到输入缓冲区;
        // 默认的8192个字节空间装满(内容结束)后;再统一读取到程序中;
        while((r=bis.read())!=-1){
        //方法public void write(int b);需要一个字节一个字节放到输出缓冲区;
        //默认的8192个字节空间装满(内容结束)后;再统一从程序向外写入目标文件;
            bos.write(r);
        }*/

        //方式2:比较高效的读写;
        //由于缓冲区的空间就是个数组;这里再创建一个相当于是双重数组;
        //实际上是使用了字节输入输出的高效读写方法;将字节放到字节中,一部分一部分地传进缓冲区;
        byte[] bytes=new byte[3072];
        //方法public int read(byte[] b);
        //每read一次就读了3072个字节的的内容;然后放到输入缓冲区;
        //注意:当这个定义的数组大于缓冲区的空间时,缓冲区会失效;内容会直接读取到程序中;
        //而不是先存到缓冲区;
        int length=0;
        while((length=bis.read(bytes))!=-1){
            //方法public void write(byte[] b, int off, int len)
            //当调用write方法时;先会判断输出缓冲区是否装满;装满后就从程序向目标文件写入;
            bos.write(bytes,0,length);
        }

        //刷新输出缓冲区;
        //public void flush()
        bos.flush();
        //关闭缓冲流;
        bis.close();
        bos.close();
    }
}

在这里插入图片描述


方式1中:
用到的方法.

  • public int read( );
    需要一个字节一个字节放到输入缓冲区;
    每次判断默认的8192个字节空间(或者指定的空间)装满后;再统一读取到程序中;
  • public void write(int b);
    需要一个字节一个字节放到输出缓冲区;
    每次判断默认的8192个字节空间(或者指定的空间)装满后;再统一从程序向外写入目标文件;
  • public void flush( )
    刷新输出缓冲区.

方式2中:
用到的方法:

  • public int read(byte[ ] b);
    读取多个字节,存到一个byte数组中,再进入输入缓冲区;判断当缓冲区装满时就全部读取到程序中;当定义的数组空间大于缓冲区默认的8192字节(或者自己指定的大小)空间;缓冲区就会失效;这时,文件会直接一个数组一个数组地读取到程序中去.

  • public int read(byte[ ] b);
    写入多个字节,存到一个byte数组中,再进入输入缓冲区,判断当缓冲区装满时就全部写入目标文件;当定义的数组空间大于缓冲区默认的8192字节(或者自己指定的大小)空间;缓冲区就会失效;这时,文件会直接一个数组一个数组地写入目标文件.



以上是关于JavaSE基础九----<IO流 >流的体系和分类,字节流,字节缓冲流的主要内容,如果未能解决你的问题,请参考以下文章

JavaSE基础九----<IO流 >字符流,字符缓冲流

基础IO流javaSe

JavaSE IO类层次关系和各种IO流的用法总结

JavaSE基础九---<IO流 >print打印流,对象输入输出流,对象序列化,transient关键字

JavaSE——IO流(缓冲流)

java基础——流体系,字符流和字节流基本用法