温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java中IO流有什么用

发布时间:2021-08-17 09:12:30 来源:亿速云 阅读:207 作者:小新 栏目:开发技术

这篇文章主要为大家展示了“Java中IO流有什么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java中IO流有什么用”这篇文章吧。

    1、IO流

    1.流和流的分类

    什么是IO流?

    I:Input (输入)

    O: Ouput(输出)

    IO流的分类?

    有多种分类方式:

    • 一种方式是按照流的方向进行分类:

    以内存作为参照物

    往内存中去,叫做输入(Input)。或者叫做读(Read) .

    从内存中出来,叫做输出(output)。或者叫做写(write) .

    • 另一种方式是按照读取薮据方式不同进行分类:

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

      • 这种流是万能的,什么类型的文件都可以读取。包括:文本文件,图片,声音文件,视频……

      • 有的流是按照字符的方式读取数据的,一次读取一个字符,这种流是为了方便读取普通文本文件而存在的,这种流不能读取:图片、声音、视频等文件。只能读取纯文本文件,连word文件都无法读取

    总结:流的分类

    输入流、输出流、字节流、字符流

    Java IO流的四大家族

    java.io.InputStream字节输入流
    java.io.OutputStream字节输出流
    java.io.Reader字符输入流
    java.io.Writer字符输出流

    注意:

    • 四个都是抽象类。

    • 所有流都是实现了java.io.Closeable接口,都是可关闭的

      • 流是一个管道,是内存和硬盘之间的通道。用完后一定要关闭,不然会占用很多资源。

    • 所有的输出流都实现了java.io.Flushable接口,都是可刷新的

      • 最终输出后,一定要记得调用flush()方法。目的是将管道中剩余未输出的数据强行输出完(清空管道)

      • 如果没有flash(),可能会导致丢失数据

    • 在java中只要”类名”以strean结尾的都是字节流。以"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.Bufferedoutputstrean

    数据流专属:

    java . io . DataInputstream

    java .io. Dataoutputstrean

    标准输出流:

    java . io . Printwriter

    java . io . Printstream

    对象专属流:

    java.io.ObjectInputstream

    java.io.ObjectOutputstream

    一下子看到这么多流。不用怕,只需要掌握一组的使用方法就可以了,使用其他的都是一样,一通百通。

    下面以万能的字节流(FileInputStream、FileOutputStream)来举例说明。

    2.如何使用流

    1、输入流(读文件):FileInputStream

    方法一

    使用FileInputStream的read()

    步骤:

    1、 创建流对象

    new FileInputStream(参数)

    参数可以是一个File类、String字符串表示的文件路径

    2、使用流的方法对文件进行读

    输入流调用read()方法,每次从流中读取一个数据字节。返回值是读到的字节的ASCII值

    读取一个后,他会指向下一个字符,如果到达末尾。返回-1,可以用while()来实现。

    3、关闭流

    调用close()方法

    实例:

    package com.io.stream;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    public class TestFileInputStream {
        //定义一个流对象
        private static FileInputStream fis;
        public static void main(String[] args) {
            try {
                //1、 创建流对象.参数可以是一个File类、String字符串表示的文件路径
                fis = new FileInputStream("E:\\aaa.txt");//在e盘下有一个aaa.txt的文件夹,内容为(abcdefg)
                //2、使用流的方法对文件进行读
                while (true) {
                    int read = fis.read();//注意这里返回的是int类型,代表是字符的ASCII值
                    if (read==-1) {//读到最后会返回-1,退出条件
                        break;
                    }
                    System.out.println(read);
                }
            } catch (FileNotFoundException e) {//异常细粒化,不同异常可以选择不同的处理方式
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    //3、关闭流
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /*输出
    97
    98
    99
    100
    101
    102
    103
    */

    int read()

    该方法因为每次都是只读取一个字节,这样内存和硬盘交互太频繁 ,开销大且效率不高。一般不使用,但是要了解,这是基础。

    方法二

    一般使用这种方法

    使用read(byte[] b)

    一次读取最多 b.length 个字节,减少内存和硬盘交互,提高执行效率

    该方法返回的是读到的字节的数量

    使用步骤:和前面只有第二步有些差别

    byte[] b= new byte[3];

    int readNum = fis.read(b);

    解析

    • 新建一个byte[]数组b,代表我们一次需要读多少个字符。读完这么多字符后,下次一读是从当前读到的位置开始,和上面一样

    • 将byte数组b传入read()方法中,返回一个我们byte数组的大小,此时readNum值为3

    那么我们读出来的数据在哪里呢。自然是存放在byte数组里。我们打印b数组看,发现b数组里存放的读到的ascii值

    细节:

    因为数组的长度是我们设定的。如果文件读到最后,不一定刚好符合我们设定的长度,最后一组的长度只有小于或等于数组的长度。如果小于它会返回剩余的字符的数量,读不到返回-1,我们可以利用这个作为循环退出的条件。

    另外一个,因为他的长度小于b数组,那么它的值也是无法填满b数组的,此时,它只更新b数组中前面的n个读到的值,b数组后面的是上一个读取时读取到的值。

    实例:

    仍然读取aaa.txt文件,内容为(abcdefg)

    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.util.Arrays;
    public class TestFileInputStream2 {
        private static FileInputStream fis;
        public static void main(String[] args) {
            try {
                fis = new FileInputStream("IO流\\aaa.txt");
                //准备一个byte数组
                byte[] b= new byte[3];
                int readNum = 0;
                while (true) {
                    //先进行读操作。
                    readNum=fis.read(b);
                    //判断
                    if (readNum == -1) {
                        break;
                    }
                    //将字符数组转为String,后面两个参数为起始位置,和长度
                    String str = new String(b, 0, readNum);
                    System.out.println(str);
                }
                /*输出
    				abc
    				def
    				g
    			*/
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    //关闭流
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    其他常用的方法

    int available()

    返回流中还有多少个字符没有读。(相当于获得文件读到的位置到末尾字符的个数,如果没开始读,返回文件中总字符的数量)

    使用这个可以对一些比较小的(字符长度)文件一次读完,如果不超过byte数组的范围的话

    public class TestFileInputStream3 {
        public static void main(String[] args) throws IOException {
            FileInputStream fis = new FileInputStream("IO流\\aaa.txt");
            byte[] bytes = new byte[fis.available()];//创建一个和文件字符数量一样大的byte数组,文件不能太大。
            fis.read(bytes);
            System.out.println(new String(bytes));//b转为字符串,输出abcdefg
        }
    }

    skip(long n)

    顾名思义:从输入流中跳过并丢弃 n 个字节的数据。

    2、输出流(写文件):FileOutputStream

    和输入的流程差不多,过程也基本相同

    write(byte[] b)

    注意:

    • byte的范围是-128~127,超过会报错

    • 写完之后,一定要刷新

    • 如果当前路径下文件已存在,会将原文件清空,再写入(慎用)。

      • 如果它是一个目录,而不是一个常规文件,会报错。

      • 或者该文件不存在,但无法创建它,会报错。

    • 如果当前路径下文件不存在,会新建文件。

    package com.io.stream.output;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    /**
     * @Author cyh
     * @Date 2021/8/7 17:21
     */
    public class Test1 {
        private static FileOutputStream fos;
        public static void main(String[] args) {
            try {
                //新建一个输出流,参数是输出的路径,最后的为文件名。
                fos = new FileOutputStream("IO流\\bbb.txt");
                //新建一个byte数组,里面对应的是abcd的ascii值
                byte[] bytes = {97, 98, 99, 100,101,127}; //注意byte的范围是-128~127
                //输出流调用write方法写入byte数组,以文件形式保存到上面的路径
                fos.write(bytes);
                //写完之后,一定要刷新
                fos.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    追加写文件

    想要追加写文件,则需要在新建流的的时候,加一个参数true。

    表示将字节写入文件末尾处,而不是写入文件开始处

    //新建一个输出流,参数是输出的路径,最后的为文件名。增加true表示开启追加写
    fos = new FileOutputStream("IO流\\bbb.txt",true);

    注意:和上面一样,不一样的点只是追加写。

    write(byte[] b, int off, int len)

    将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流.

    意思就是,写入的内容为off~len。如果off是0,len是数组长度,那就全部写入;如果off是数组长度-1,len是数组长度,那就只写入了一个字符

    3.文件的拷贝

    • 使用FileInputStream+FileOutputStream即可完成文件的拷贝

    • 拷贝的过程应该是一边读、一边写

    • 使用上面的字节流拷贝文件的时候,文件类型随意,是万能的。什么文件都可以拷贝

    实例

    package com.io.stream.copy;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    /**
     * @Author cyh
     * @Date 2021/8/7 17:53
     */
    public class TestCopy {
        private static FileInputStream fis;
        private static FileOutputStream fos;
        public static void main(String[] args) {
            try {
                //创建一个输入流
                fis = new FileInputStream("D:\\edgeDownload\\VSCodeUserSetup-x64-1.55.0.exe");
                //创建一个输出流
                fos = new FileOutputStream("C:\\Users\\PC\\Desktop\\copy\\b\\VSCodeUserSetup-x64-1.55.0.exe");
                //核心,一边读、一边写
                byte[] bytes = new byte[1024*1024];//1MB,一次最多拷贝1MB
                int readNum=0;
                while((readNum=fis.read(bytes))!=-1){
                    fos.write(bytes,0,readNum);//将bytes全部写入
                }
                //刷新
                fos.flush();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                //资源要分开释放,不然一个出错会导致另一个无法释放
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    以上是“Java中IO流有什么用”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI