JAVA_IO流四大家族(1)

JAVA_IO四大家族体系:

JAVA_IO流四大家族(1)

JAVA_IO流四大家族(2)

常识介绍

IO流,什么是IO?

I:Input
O:Output
通过IO可以完成硬盘文件的读写

IO流的分类:

一种方式是按照流的方向进行分类:
以内存为参照物,
往内存中去,叫做输入,或者叫做读,
从内存中出来,叫做输出,或者叫做写

另一种方式是按照读写数据方式不同进行分类:
有的流是按照字节的方式读取数据,一次读取一个字节byte,等同于一次读取8个二进制位,这种流是万能的,什么类型的文件都能读取。包括:文本文件,图片,声音文件,视频

假设文件file.txt,采用字节流是这样读的:
a中国bc张三fe

第一次读:一个字节,正好读到’a‘,
第二次读:一个字节,正好读完‘中’字符的一半
第三次读:一个字节,正好读到‘中’字符的另外一半

有的流是按照字符的方式读取数据的,一次读取一个字符,这种流是为了方便读取普通文本文件而存在的,这种流不能读取:图片,声音,视频等文件,只能读取纯文本文件,连word文件都没法读取。
假设文件file.txt,采用字符流是这样读的:
a中国bc张三fe
第一次读:'a’字符('a’字符在windows系统中占有一个字节)
第二次读:'中’字符('a’字符在windows系统中占有两个字节)

综上所述:流的分类
输入流,输出流
字节流,字符流

JAVA中主要研究:

怎么new流对象
调用流对象的哪个方法读,哪个方法写

四个家族首领

java.io.InputStream 字节输入流
java.io.OutputStream 字节输出流

扫描二维码关注公众号,回复: 12739751 查看本文章

java.io.Reader 字符输入流
java.io.Writer 字符输出流

四大家族首领都是抽象类(abstract class)

所有的流都实现了:java.io.Closeable接口,都是可关闭的,都有close()方法。
流毕竟是一个管道,这个是内存和硬盘之间的通道,用完之后一定要关闭,不然会耗费很多资源。养成好习惯,用完流一定要关闭

所有的输出流都实现了:
java.io.Flushable接口,都是可刷新的,都有flush()方法;养成好习惯,输出流在最终输出之后,一定要记得flush()刷新一下,这个刷新表示将通道/管道当中剩余未输出的数据强行输出完(清空管道)刷新的作用就是清空管道
注意:如果没有flush()可能会导致丢失数据;还有只有输出流有flush(),输入流并没有

在这里插入图片描述

注意:在java中只要“类名”以Stream结尾的都是字节流,以“Reader/Writer”结尾的都是字符流

java.io包下需要掌握的流有16个:

文件专属:
java.io.FileInputStream
java.io.FileOutputStream
java.io.FileReader
java.io.FileWriter

转换流:(将字节流转换为字符流)
java.io.InputStreamReader
java.io.OutputStreamWriter

缓冲流专属:
java.io.BufferedReader
java.io.BufferedWriter
java.io.BufferedInputStream
java.io.BufferedOutputStream

数据流专属:
java.io.DataInputStream
java.io.DataOutputSteam

标准输出流:
java.io.PrintWriter
java.io.PrintStream

对象专属流:
java.io.ObjectInputStream
java.io.ObjectOutputStream

FileInputStream

read方法

调用一次read方法,文件指针会往后移动一位,即如下图
在这里插入图片描述

当执行到f下一个位置时,read返回值就为-1,那么这种read()读取实现的话,就可以用循环来实现

read方法1代码


/*
* 1.文件字节输出流,万能的,任何类型的文件都可以采用这个流来读
* 2.字节的方式,完成输入的操作,完成读的操作(硬盘--->内存)
* */

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest01 {
    
    
    public static void main(String[] args) {
    
    
    //创建文件字节输入流对象
        // 文件路径:(IDEA会自动把\编程\\,因为java中\代表转义)
        FileInputStream fis=null;
        try {
    
    
            fis=new FileInputStream("G:\\test.txt");

            //开始读
            int readData =fis.read();//这个方法的返回值是:读取到的“字节”本身
             System.out.print(readData+"\n");

             readData =fis.read();//这个方法的返回值是:读取到的“字节”本身
              System.out.print(readData+"\n");

            
             readData =fis.read();//这个方法的返回值是:读取到的“字节”本身
             System.out.print(readData+"\n");


        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            //在finally语句块中确保流一定关闭
            if(fis!=null){
    
    //避免空指针异常
        //关闭流的前提是:流不是空
                try {
    
    
                    fis.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}

在这里插入图片描述

read方法1实现截图

在这里插入图片描述

read方法2代码

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest02 {
    
    
    public static void main(String[] args) {
    
    
        FileInputStream fis=null;
        try {
    
    
            fis=new FileInputStream("G:\\test.txt");
            while(true){
    
    
                int readData=fis.read();
                if(readData==-1){
    
    
                    break;
                }
                System.out.println(readData);
            }
        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if(fis!=null){
    
    
                try {
    
    
                    fis.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }

            }
        }

    }
}

改造后for循环

  int readData=0;
            while((readData=fis.read())!=-1){
    
    
                System.out.println(readData);
            } 

read方法2实现截图

在这里插入图片描述

在这里插入图片描述

read方法3代码

IDEA默认的当前路径是哪里?

首先得搞懂这个问题,我们在src下面创建一个tempfile
在这里插入图片描述
在这里插入图片描述

然后执行以下代码:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest03 {
    
    
    /*
    *
    * int read(byte[] b)
    * 一次最多读取b.length个字节
    * 减少硬盘和内存的交互,提高程序的执行效率
    * 往byte数组当中读
    * */
    public static void main(String[] args) {
    
    
        FileInputStream fis=null;
        try {
    
    
            //相对路径的话呢?相对路径一定是从当前所在的位置作为起点开始找
            //IDEA默认的当前路径是哪里?工程project的根就是IDEA的默认当前路径
            fis=new FileInputStream(
                    "tempfile");
        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            if(fis!=null){
    
    
                try {
    
    
                    fis.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }


    }
}

毫无疑问,报错

在这里插入图片描述
找不到指定文件,很简单的原因,当前路径想错了

两个解决办法:

第一个 办法

在这里插入图片描述
先找到文件所在path
在这里插入图片描述

重点

IDEA默认的当前路径是哪里?工程project的根就是IDEA的默认当前路径

tempfile文件拷贝一份,放在工程project的根,也就是当前的上层目录
在这里插入图片描述
拷贝完成,然后再次执行上述代码

在这里插入图片描述
运行成功

第二个 办法

把如下代码

fis=new FileInputStream(
                    "tempfile");

变成

fis=new FileInputStream(
                    "src//tempfile");

在这里插入图片描述
在这里插入图片描述
执行结果如下
在这里插入图片描述

操作过程(如何看长度)

开始读,采用byte数组,一次读取多个字节,最多读取“数组.length”个字节

   byte []bytes=new byte [4];//准备一个4个长度的数组,一次最多读取4个字节
第一次调用read(bytes)如下图:

在这里插入图片描述

 int readCount= fis.read(bytes);

这个方法的返回值是:读取到的字节数量(不是字节本身),数据已经放在了bytes数组中去
在这里插入图片描述

第二次调用read(bytes)如下图:

在这里插入图片描述
这次读取到了两个字节

readCount= fis.read(bytes);
System.out.println(readCount);//第二次只能读到2个字节

在这里插入图片描述

第三次调用read(bytes)

读不到任何数据返回-1

 readCount= fis.read(bytes);//第三次1个字节都没有读取到,返回-1
System.out.println(readCount);//-1

在这里插入图片描述

操作过程(如何看读取出的数据)

在这里插入图片描述

  //这个方法的返回值是:读取到的字节数量(不是字节本身)
            int readCount= fis.read(bytes);

            System.out.println(readCount);//第一次读到了4个字节
            System.out.println(new String(bytes));

             readCount= fis.read(bytes);
            System.out.println(new String(bytes));
           // System.out.println(readCount);//第二次只能读到2个字节

在这里插入图片描述

第二次只读取两个字节,然后它把读取到的5和6放在1和2位置处,但是原来数组中3和4还依然存在,这也就符合我们下图所表示的
在这里插入图片描述

操作过程注意点

问题来了,我们应该是读取了多少个,就写多少个,(不应该全部转换)而不是写数组的全部进入String中,应该用如下形式
在这里插入图片描述

  //开始读,采用byte数组,一次读取多个字节,最多读取“数组.length”个字节
            byte []bytes=new byte [4];//准备一个4个长度的数组,一次最多读取4个字节

            //这个方法的返回值是:读取到的字节数量(不是字节本身)
            int readCount= fis.read(bytes);

            System.out.println(readCount);//第一次读到了4个字节
            System.out.println(new String(bytes,0,readCount));

             readCount= fis.read(bytes);
            System.out.println(new String(bytes,0,readCount));
           // System.out.println(readCount);//第二次只能读到2个字节

            readCount= fis.read(bytes);//第三次1个字节都没有读取到,返回-1

在这里插入图片描述

总结实现代码

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest04 {
    
    
    public static void main(String[] args)  {
    
    
        FileInputStream fis=null;

        try {
    
    
            fis=new FileInputStream("src//tempfile");
            //准备一个byte数组
            byte[]bytes=new byte[4];
            int readCount=0;
            while(true){
    
    
                 readCount=fis.read(bytes);
                if(readCount==-1){
    
    
                    break;
                }
                System.out.print(new String(bytes,0,readCount));
            }
        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if(fis!=null){
    
    
                try {
    
    
                    fis.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}

在这里插入图片描述

改版后的while循环
  int readCount1=0;
            while((readCount1=fis.read(bytes))!=-1){
    
    
                System.out.print(new String(bytes,0,readCount1));
            }
            

available方法

int available()

返回流当中剩余的没有读到的字节数量

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest05 {
    
    
    public static void main(String[] args)  {
    
    
        FileInputStream fis=null;

        try {
    
    
            fis=new FileInputStream("");
            
            System.out.println("总字节数量"+fis.available());
            
            //读取1个字节
            int readByte=fis.read();
            //还剩下可以读的字节数量是5;
            
              System.out.println("剩下多少字节没有读:"+fis.available()+"字节");
            
        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if(fis!=null){
    
    
                try {
    
    
                    fis.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}

在这里插入图片描述

作用如下:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest05 {
    
    
    public static void main(String[] args)  {
    
    
        FileInputStream fis=null;

        try {
    
    
            fis=new FileInputStream("src//tempfile");

            System.out.println("总字节数量"+fis.available());
            
            //这个方法有什么用?
            byte []bytes=new byte[fis.available()];//这种方式不太适合太大的文件,因为byte数组不能太大
            //不需要循环了
            //直接读一次就行了
            int readCount=fis.read(bytes);
            System.out.print(new String(bytes));//一次到位

        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if(fis!=null){
    
    
                try {
    
    
                    fis.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}

在这里插入图片描述

注意:

这种方式不太适合太大的文件,因为byte数组不能太大

skip方法

跳过几个字节不读取

long skip (long n)

实现代码

public class FileInputStreamTest05 {
    
    
    public static void main(String[] args)  {
    
    
        FileInputStream fis=null;

        try {
    
    
            fis=new FileInputStream("src//tempfile");

      
            fis.skip(3);
            System.out.print(fis.read());

        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if(fis!=null){
    
    
                try {
    
    
                    fis.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}

在这里插入图片描述
字符4的ASCII码值是52
在这里插入图片描述

FileOutputStream

实现代码1(清空再写入)

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamTest01 {
    
    
    /*
    * 文件字节输出流,负责写
    * 从内存到硬盘
    * */
    public static void main(String[] args) {
    
    
        FileOutputStream fos=null;

        try {
    
    
           
            fos=new FileOutputStream("myfile");

            //开始写
            byte[]bytes={
    
    97,98,99,100};

            fos.write(bytes);

            fos.write(bytes,0,2);//再写出ab

            //写完之后,最后一定要刷新
            fos.flush();
        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if(fos!=null){
    
    
                try {
    
    
                    fos.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}

注意点

  1. myfile文件不存在时会自动新建
  2. 这种方式谨慎使用,这种方式会将原文件清空,然后重新写入

实现代码2(以追加的方式)

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

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamTest01 {
    
    
    /*
    * 文件字节输出流,负责写
    * 从内存到硬盘
    * */
    public static void main(String[] args) {
    
    
        FileOutputStream fos=null;

        try {
    
    
            //myfile文件不存在时会自动新建
            //这种方式谨慎使用,这种方式会将原文件清空,然后重新写入
            fos=new FileOutputStream("myfile",true);

            //开始写
            byte[]bytes={
    
    97,98,99,100};

            fos.write(bytes);

            fos.write(bytes,0,2);//再写出ab

            //写完之后,最后一定要刷新
            fos.flush();
        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if(fos!=null){
    
    
                try {
    
    
                    fos.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}

注意点

  1. myfile文件不存在时会自动新建
  2. 以追加的方式在文件末尾写入,不会清空原文件内容

实现截图

执行前:
在这里插入图片描述
执行后:
在这里插入图片描述

如何写入一个String字符串


          import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamTest01 {
    
    
    /*
    * 文件字节输出流,负责写
    * 从内存到硬盘
    * */
    public static void main(String[] args) {
    
    
        FileOutputStream fos=null;

        try {
    
    
            //myfile文件不存在时会自动新建
            //这种方式谨慎使用,这种方式会将原文件清空,然后重新写入
            fos=new FileOutputStream("myfile",true);

            String s="我是一个中国人,我自豪";

            byte[] bytes3=s.getBytes();

            fos.write(bytes3);

            //写完之后,最后一定要刷新
            fos.flush();
        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if(fos!=null){
    
    
                try {
    
    
                    fos.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}


在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/CSNN2019/article/details/114344174