JAVA_IO流四大家族(1)

JAVA_IO四大家族体系:

JAVA_IO流四大家族(1)

JAVA_IO流四大家族(2)

文章目录

  • JAVA_IO四大家族体系:
    • JAVA_IO流四大家族(1)
    • JAVA_IO流四大家族(2)
  • 常识介绍
    • IO流,什么是IO?
    • IO流的分类:
    • JAVA中主要研究:
    • 四个家族首领
    • java.io包下需要掌握的流有16个:
  • FileInputStream
    • read方法
      • read方法1代码
      • read方法1实现截图
      • read方法2代码
        • 改造后for循环
      • read方法2实现截图
      • read方法3代码
          • IDEA默认的当前路径是哪里?
          • 毫无疑问,报错
        • 两个解决办法:
          • 第一个 办法
            • 重点
          • 第二个 办法
          • 操作过程(如何看长度)
            • 第一次调用`read(bytes)`如下图:
            • 第二次调用`read(bytes)`如下图:
            • 第三次调用`read(bytes)`:
          • 操作过程(如何看读取出的数据)
            • 操作过程注意点
        • 总结实现代码
          • 改版后的while循环
    • available方法
      • 作用如下:
      • 注意:
    • skip方法
      • 实现代码
  • FileOutputStream
    • 实现代码1(清空再写入)
      • 注意点
    • 实现代码2(以追加的方式)
      • 注意点
      • 实现截图
      • 如何写入一个String字符串

常识介绍

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 字节输出流

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

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

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

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

JAVA_IO流四大家族(1)_第1张图片

注意:在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方法,文件指针会往后移动一位,即如下图
JAVA_IO流四大家族(1)_第2张图片

当执行到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();
                }
            }
        }
    }
}

JAVA_IO流四大家族(1)_第3张图片

read方法1实现截图

JAVA_IO流四大家族(1)_第4张图片

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实现截图

JAVA_IO流四大家族(1)_第5张图片

JAVA_IO流四大家族(1)_第6张图片

read方法3代码

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

首先得搞懂这个问题,我们在src下面创建一个tempfile
JAVA_IO流四大家族(1)_第7张图片
在这里插入图片描述

然后执行以下代码:

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();
                }
            }
        }


    }
}

毫无疑问,报错

JAVA_IO流四大家族(1)_第8张图片
找不到指定文件,很简单的原因,当前路径想错了

两个解决办法:

第一个 办法

JAVA_IO流四大家族(1)_第9张图片
先找到文件所在path
JAVA_IO流四大家族(1)_第10张图片

重点

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

tempfile文件拷贝一份,放在工程project的根,也就是当前的上层目录
JAVA_IO流四大家族(1)_第11张图片
拷贝完成,然后再次执行上述代码

JAVA_IO流四大家族(1)_第12张图片
运行成功

第二个 办法

把如下代码

fis=new FileInputStream(
                    "tempfile");

变成

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

JAVA_IO流四大家族(1)_第13张图片
JAVA_IO流四大家族(1)_第14张图片
执行结果如下
JAVA_IO流四大家族(1)_第15张图片

操作过程(如何看长度)

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

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

JAVA_IO流四大家族(1)_第16张图片

 int readCount= fis.read(bytes);

这个方法的返回值是:读取到的字节数量(不是字节本身),数据已经放在了bytes数组中去
JAVA_IO流四大家族(1)_第17张图片

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

JAVA_IO流四大家族(1)_第18张图片
这次读取到了两个字节

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

JAVA_IO流四大家族(1)_第19张图片

第三次调用read(bytes)

读不到任何数据返回-1

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

JAVA_IO流四大家族(1)_第20张图片

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

在这里插入图片描述

  //这个方法的返回值是:读取到的字节数量(不是字节本身)
            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个字节

JAVA_IO流四大家族(1)_第21张图片

第二次只读取两个字节,然后它把读取到的5和6放在1和2位置处,但是原来数组中3和4还依然存在,这也就符合我们下图所表示的
JAVA_IO流四大家族(1)_第22张图片

操作过程注意点

问题来了,我们应该是读取了多少个,就写多少个,(不应该全部转换)而不是写数组的全部进入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

JAVA_IO流四大家族(1)_第23张图片

总结实现代码

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();
                }
            }
        }
    }
}

JAVA_IO流四大家族(1)_第24张图片

改版后的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();
                }
            }
        }
    }
}

JAVA_IO流四大家族(1)_第25张图片

作用如下:

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();
                }
            }
        }
    }
}

JAVA_IO流四大家族(1)_第26张图片

注意:

这种方式不太适合太大的文件,因为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();
                }
            }
        }
    }
}

JAVA_IO流四大家族(1)_第27张图片
字符4的ASCII码值是52
JAVA_IO流四大家族(1)_第28张图片

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(以追加的方式)

JAVA_IO流四大家族(1)_第29张图片
JAVA_IO流四大家族(1)_第30张图片

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. 以追加的方式在文件末尾写入,不会清空原文件内容

实现截图

执行前:
JAVA_IO流四大家族(1)_第31张图片
执行后:
JAVA_IO流四大家族(1)_第32张图片

如何写入一个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();
                }
            }
        }
    }
}


JAVA_IO流四大家族(1)_第33张图片

你可能感兴趣的:(java)