首页 > 其他 > 详细

IO流 - 汇总

时间:2021-04-24 20:28:13      阅读:20      评论:0      收藏:0      [点我收藏+]

1、IO流的分类

1.1、按照流的方向进行分类:以内存作为参照物,

  • 往内存中去,叫做输入(Input)。或者叫做读(Read)。
  • 从内存中出来,叫做输出(Output)。或者叫做写(Write)。

1.2、按照读取数据方式不同进行分类:

  • 按照字节的方式读取数据,一次读取1个字节byte,等同于一次读取8个二进制位。

    • 读取类型:文本文件,图片,声音文件,视频文件等....

    • 实例:

      假设文件file1.txt,采用字节流的话是这样读的:
      	a中国bc张三fe
      	第一次读:一个字节,正好读到‘a‘
      	第二次读:一个字节,正好读到‘中‘字符的一半。
      	第三次读:一个字节,正好读到‘中‘字符的另外一半。
      
  • 按照字符的方式读取数据的,一次读取一个字符,这种流是为了方便读取普通文本文件而存在的。

    • 读取类型:普通文本文件,例如:.txt,.java等文件;可以使用记事本打开的都是普通文本文件。(连word文件都无法读取。)

    • 实例:

      假设文件file1.txt,采用字符流的话是这样读的:
      	a中国bc张三fe
      	第一次读:‘a‘字符(‘a‘字符在windows系统中占用1个字节;‘a‘在java中占用2个字节。1char)
      	第二次读:‘中‘字符(‘中‘字符在windows系统中占用2个字节。)
      

2、IO流的四大家族

  • 四大家族的首领都是抽象类(abstract class)。
  • 所有流都实现了java.io.Closeable接口,都是可关闭的,都有close()方法。
  • 所有输出流都实现了java.io.Flushable接口,都是可刷新的,都有flush()方法。刷新管道是为了将管道中的数据强行输出,避免数据丢失。
  • 在java中只要“类名”以Stream结尾的都是字节流。以“Reader/Writer”结尾的都是字符流。

2.1、java.io.InputStream(字节输入流)

2.2、java.io.OutputStream(字节输出流)

2.3、java.io.Reader(字符输入流)

2.4、java.io.Writer(字符输出流)

3、常用IO流

3.1、文件专属:

3.1.1、java.io.FileInputStream(掌握)


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

public class FileInputStreamTest001 {
    public static void main(String[] args) {
        //下面需要关闭流,所以fil只能声明在这里。
        FileInputStream fil=null;
        try {
            //这里的文件名可以是绝对路径或者相对路径;相对路径是以项目名问根。该文件内容:abcdefg
            fil=new FileInputStream("LX\\src\\file");

            //单个读取, 返回的是字节本身。如果全部读取完后,再继续读取时返回-1。
            int readData=fil.read();
            System.out.println(readData);

            //使用while循环读取所有字节
            while (true){
                int readData1=fil.read();
                if (readData1==-1){
                    break;
                }
                System.out.println(readData1);
            }

            //使用while循环读取所有字节(改良版)
            int readData2;
            while ((readData2=fil.read())!=-1){
                System.out.println(readData2);
            }

            //使用byte数组读取字节
            //创建一个数组,长度为4
            byte[] bytes=new byte[4];
            //这里返回的是字节数量,不是字节本身;字节已经存到数组中了。
            int readCount=fil.read(bytes);
            //将数组转化成字符串输出,输出的是数组中的四个元素
            System.out.println(new String(bytes));
            //再一次读取到数组是,efgd。只剩下3个字节,只能覆盖数组中的前3个位置,第四个位置的d没有覆盖,直接又输出。
            readCount=fil.read(bytes);
            System.out.println(new String(bytes));
            //再一次读取时,文件中的内容已经读取完了,这次返回的是-1
            readCount=fil.read(bytes);
            //这次读取时,输出的依然是数组最后一次覆盖的数据,即 和上一次一样。
            System.out.println(new String(bytes));

            //改良版
            //将数组转换成字符串时,读到多少就转换多少,即,从下标0开始,转换读取到的字节数量。
            System.out.println(new String(bytes,0,readCount));

            //使用数组和while循环读取
            byte[] bytes1=new byte[4];
            while (true){
                int readCount1=fil.read(bytes1);
                if (readCount1==-1){
                    break;
                }
                System.out.println(new String(bytes1,0,readCount1));
            }

            //使用数组和while循环读取(改良版)
            byte[] bytes2=new byte[4];
            int readCount2=0;
            while ((readCount2=fil.read(bytes2))!=-1){
                System.out.println(new String(bytes2,0,readCount2));
            }
            

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //判断流是否为null,如果为null时,关闭执行关闭语句的话,会报空指针异常。
            if (fil != null) {
                try {
                    fil.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

常用方法:

  • 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("LX\\src\\file");

            //一个字节都还没有读,所以剩余7的字节。
            System.out.println("总字节数量:" + fis.available());

            //这种方式不适合大文件,因为byte[]数组不能太大
            byte[] bytes = new byte[fis.available()];

            //不需要循环,直接就可以将数组转换成字符串
            System.out.println(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();
                }
            }
        }
    }
}
  • long skip(long n):跳过几个字节不读。
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("LX\\src\\file");

            fis.skip(3);
            System.out.println(fis.read()); //100,100对应的是d

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

3.1.2、java.io.FileOutputStream(掌握)

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

public class FileOutputStreamTest001 {
    public static void main(String[] args) {
        FileOutputStream fos=null;

        try {
            //文件夹不存在的话,会自动创建;后面的true表示在在文件末尾写入;否则会覆盖。
            fos=new FileOutputStream("file01",true);

            //创建一个数组
            byte[] bytes={97,98,99};

            //表示从下标为0开始,写入两个字节;如果没有后面两个参数,表示全部写入。
            fos.write(bytes,0,2);

            //写完之后一定要刷新
            fos.flush();

            //需要写入字符串时,先把字符串转成数组
            String s="你是个好人";
            byte[] bytes1=s.getBytes();

            //写入数组中的全部字节
            fos.write(bytes1);

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

文件复制:综合java.io.FileInputStream和java.io.FileOutputStream

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

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

        try {
            //创建输入流
            fis= new FileInputStream("E:\\百度网盘文件下载位置\\Visio 2019 专业版.zip");
            //创建输出流
            fos=new FileOutputStream("E:\\Visio 2019 专业版.zip");

            //创建一个数组
            byte[] bytes=new byte[1024*1024];	//等于1M

            //读入内存的同时写入硬盘
            int reafCount=0;
            while ((reafCount=fis.read(bytes))!=-1){
                fos.write(bytes,0,reafCount);
            }

            //写入要刷新
            fos.flush();
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (fos != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3.1.3、java.io.FileReader

  • 这个是文件字符输入流,只能读取文本。
  • 使用方法参考上面:java.io.FileInputStream。
  • 与参考的还是有点区别的:
    • 上面使用的是byte数组;这里使用的是char数组。

3.1.4、java.io.FileWriter

  • 这个是文件字符输出流,只能写出文本。
  • 使用方法参考上面:java.io.FileOutputStream
  • 与参考的还是有点区别的:
    • 上面使用的是byte数组;这里使用的是char数组。
    • 上面输入字符串的话,需要将字符串转换成数组,再把数组写进去;这里的话,字符串可以直接放在写入方法里面进行写入,例fos.write{"我是一名java工程师"}

文件复制:综合java.io.FileReader和java.io.FileWriter

package com.bjpowernode.java.io;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Copy02 {
    public static void main(String[] args) {
        FileReader in = null;
        FileWriter out = null;
        try {
            // 读
            in = new FileReader("java/io/Copy02.java");
            // 写
            out = new FileWriter("Copy02.java");

            // 一边读一边写:
            char[] chars = new char[1024 * 512]; // 1MB,这个是字符,1个字符等于2个字节。
            int readCount = 0;
            while((readCount = in.read(chars)) != -1){
                out.write(chars, 0, readCount);
            }

            // 刷新
            out.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3.2、转换流:(将字节流转换成字符流)

3.2.1、java.io.InputStreamReader

该内容包含在下面java.io.BufferedReader的第二个知识点代码中。

3.2.2、java.io.OutputStreamWriter

该内容包含在栽面java.io.BufferedWriter的第二个知识点代码中

3.3、缓冲流专属:

3.3.1、java.io.BufferedReader

  • 带缓冲字符流,要是传入的"节点流"是"字符流"的话,那可以直接传入使用。
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderTest01 {
    public static void main(String[] args) {
        FileReader read=null;
        BufferedReader buf=null;

        try {
            read=new FileReader("E:\\测试.txt");

            //创建一个缓冲流,构造方法需要传入的也是一个流,所以,就不能直接写路径了。
            //刚好上面的FileReader和这个都是继承Reader的,那么传入FileReader流也可以的。
            //被传进来的叫“字节流”,外部负责包装的叫“包装流”或者叫“处理流”。这两个流都是相对来说的。
            //就下面一行而言,FileReader就是一个节点流。BufferedReader就是包装流/处理流。
            buf=new BufferedReader(read);

            //readLine()是BufferedReader中的方法,一次读取一行,所以这里不需要使用数组。
            //该方法不会自动换行,如果有字符就读取,没有的话就返回null
            String s=null;
            while ((s=buf.readLine())!=null){
                System.out.println(s);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (buf != null) {
                try {
                    //这里只需要关闭包装流,关闭包装流后,字节流会自动关闭。
                    buf.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • 带缓冲字符流,要是传入的"节点流"是"字节流"的话,需要转换流才可以使用。
import java.io.*;

public class BufferedReaderTest01 {
    public static void main(String[] args) {
        FileInputStream read=null;
        InputStreamReader insr=null;
        BufferedReader buf=null;

        try {
            read= new FileInputStream("E:\\测试.txt");
            insr=new InputStreamReader(read);
            buf=new BufferedReader(insr);

            String s=null;
            while ((s=buf.readLine())!=null){
                System.out.println(s);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (buf != null) {
                try {
                    buf.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3.3.2、java.io.BufferedWriter

  • 带缓冲字符流,要是传入的"节点流"是"字符流"的话,那可以直接传入使用。
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class BufferedWriter1 {
    public static void main(String[] args) {
        FileWriter f=null;
        BufferedWriter bu=null;
        try {
            f=new FileWriter("E:\\测试.txt",true);
            bu=new BufferedWriter(f);

            //写入
            bu.write("nihao");
            bu.write("\n");
            bu.write("你是个好人");

            //刷新
            bu.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (bu != null) {
                try {
                    bu.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • 带缓冲字符流,要是传入的"节点流"是"字节流"的话,需要转换流才可以使用。
import java.io.*;

public class BufferedWriter1 {
    public static void main(String[] args) {
        FileOutputStream f=null;
        OutputStreamWriter ou=null;
        BufferedWriter bu=null;
        try {
            f= new FileOutputStream("E:\\测试.txt",true);
            ou=new OutputStreamWriter(f);
            bu=new BufferedWriter(ou);

            //写入
            bu.write("nihao");
            bu.write("\n");
            bu.write("你是个好人");

            //刷新
            bu.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (bu != null) {
                try {
                    bu.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3.3.3、java.io.BufferedInputStream

  • 带缓冲字节流,要是传入的"节点流"是"字节流"的话,那可以直接传入使用。
  • 关于带缓冲字节流是否可以读取字符流文件,不知道,还没有测试。
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class BufferedIntputStream001 {
    public static void main(String[] args) {
        FileInputStream fileInputStream= null;
        BufferedInputStream bufferedInputStream=null;
        try {
            fileInputStream = new FileInputStream("file01");
            bufferedInputStream=new BufferedInputStream(fileInputStream);


            //数组的大小会印象到读取的数据,如果数组只剩一个字节,但下一个是中文,这时就会出现乱码,因为一个字节装不下一个中文。
            byte[] bytes=new byte[7];
            int readCount=0;
            while ((readCount=bufferedInputStream.read(bytes))!=-1){
                System.out.println(new String(bytes,0,readCount));
            }

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

3.3.4、java.io.BufferedOutputStream

  • 带缓冲字节流,要是传入的"节点流"是"字节流"的话,那可以直接传入使用。
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;

public class BufferedOutputStream001 {
    public static void main(String[] args) {
        FileOutputStream fileWriter=null;
        BufferedOutputStream bufferedOutputStream=null;
        try {
            //字节流
            fileWriter = new FileOutputStream("file01",true);
            //包装类/处理类
            bufferedOutputStream=new BufferedOutputStream(fileWriter);

            String s="n你是真的好";
            byte[] bytes=s.getBytes();

            bufferedOutputStream.write(bytes);

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

3.4、数据流专属:

3.4.1、java.io.DataInputStream

  • 这个流可以将数据连同数据的类型一并写入文件;不是普通文本。
import java.io.DataOutputStream;
import java.io.FileOutputStream;

public class DataOutputStreamTest {
    //这里的异常不建议这样抛,最好像上面一样处理异常。
    public static void main(String[] args) throws Exception{
        // 创建数据专属的字节输出流
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("data"));
        // 写数据
        byte b = 100;
        short s = 200;
        int i = 300;
        long l = 400L;
        float f = 3.0F;
        double d = 3.14;
        boolean sex = false;
        char c = ‘a‘;
        // 写入文件
        dos.writeByte(b); // 把数据以及数据的类型一并写入到文件当中。
        dos.writeShort(s);
        dos.writeInt(i);
        dos.writeLong(l);
        dos.writeFloat(f);
        dos.writeDouble(d);
        dos.writeBoolean(sex);
        dos.writeChar(c);

        // 刷新
        dos.flush();
        // 关闭最外层
        dos.close();
    }
}

3.4.2、java.io.DataOutputStream

  • DataOutputStream写的文件,只能使用DataInputStream去读。并且读的时候你需要提前知道写入的顺序。读的顺序需要和写的顺序一致。才可以正常取出数据。
import java.io.DataInputStream;
import java.io.FileInputStream;

public class DataInputStreamTest01 {
    public static void main(String[] args) throws Exception{
        DataInputStream dis = new DataInputStream(new FileInputStream("data"));
        // 开始读
        byte b = dis.readByte();
        short s = dis.readShort();
        int i = dis.readInt();
        long l = dis.readLong();
        float f = dis.readFloat();
        double d = dis.readDouble();
        boolean sex = dis.readBoolean();
        char c = dis.readChar();

        System.out.println(b);
        System.out.println(s);
        System.out.println(i + 1000);
        System.out.println(l);
        System.out.println(f);
        System.out.println(d);
        System.out.println(sex);
        System.out.println(c);

        dis.close();
    }
}

3.5、标准输出流:

3.5.1、java.io.PrintWriter

3.5.2、java.io.PrintStream(掌握)

3.6、对象专属流:

3.6.1、java.io.ObjectInputStream(掌握)

3.6.2、java.io.ObjectOutputStream(掌握)

IO流 - 汇总

原文:https://www.cnblogs.com/LFR-21/p/14697651.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!