Java重点 | IO流中的文件专属流

举报
几分醉意. 发表于 2022/10/29 21:47:38 2022/10/29
【摘要】 上一文我们已经初步认识了IO流,本文我们继续学习,本文主要介绍了IO流中的文件专属流分别是java.io.FileInputstream、java.io.FileOutputstream、java.io.FileReader、java.io.FileWriter。本文会通过代码实战的方式让你对这些流的理解更加深刻。

文件专属

FileInputstream(读 字节)

java.io.FileInputStream:
1、文件字节输入流,万能的,任何类型的文件都可以采用这个流来读。
2、字节的方式,完成输入的操作,完成读的操作(硬盘—>内存)

Read()方法:读取内容,返回值是读到几个数量,就返回几,当读完的时候,返回-1,就代表没有了

public class FileInputStream{
    public static void main(String[] args) throws IOException {
        FileInputStream fis = null;
        try {
            //创建文件字节流输入对象
            fis = new FileInputStream("D:\\AJava\\新建文件夹\\aaa");
           /* while (true){
                int rea = fis.read(); //read():读文件
                if (rea == -1 ){
                    break;
                }
                System.out.println(rea);
            }*/
            //改造while
            int aaa = 0;
            while ((aaa= fis.read())!=-1){
                System.out.println(aaa);
            }


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            //关闭流的前提是流不是空,流是空没有必要关
            if (fis != null) {
                fis.close();
            }
        }

    }
}

分析以上程序的缺点:
一次读取一个字节byte,这样内存和硬盘交互太频繁,基本上时间/资源都耗费在交互上面了。能不能一次读取多个字节呢?可以。

public class FileInputStream读最终版 {
    public static void main(String[] args) {
        FileInputStream fil = null;
        try {
            //创建文件字节输入流
            fil = new FileInputStream("JAVAse进阶/src/IO流/aa");
            //开始读,采用byte数组,一次读取多个字节。最多读取“数组.length”个字节
            byte[] bytes= new byte[4];//准备一个4个长度的byte数组,一次最多读取4个字节
/*            while (true){
                int rea = fil.read(bytes);
                if (rea==-1){
                    break;
                }
                System.out.print(new String(bytes,0,rea));
            }*/
            int aaa=0; //提前准备一个变量
            while ((aaa=fil.read(bytes))!=-1){
                //使用String构造方法,将byte转换为字符串,从0开始,到aaa结束,转换这么多
                //aaa返回的是读取字节数量。
                System.out.print(new String(bytes,0, aaa));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fil != null) {
                try {
                    fil.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

FileInputStream类的其他常用方法

FileInputstream类的其它常用方法:
int available():返回流当中剩余的没有读到的字节数量
Long skip(long n):跳过几个字节不读。

public class FileInputStream类的其他常用方法 {
    public static void main(String[] args) {
        FileInputStream fil = null;
        try {
            fil = new FileInputStream("JAVAse进阶/src/IO流/aa");
            System.out.println(fil.available());
            //准备一个长度为fil.available长度的数组,一次最多读fil.available()个字节
            byte[] bytes = new byte[fil.available()];// 这种方式不太适合太大文件,因为byte数组不能太大
            //不需要循环了,直接读一次就行了,返回的是一次读到的字节
            int read = fil.read(bytes);
            //读取到的字节转换为字符串输出
            System.out.println(new String(bytes));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fil != null) {
                try {
                    fil.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

FileOutputStream (写 字节)

文件字节输出流,负责写。从内存到硬盘。

public class FileOutputStream{
    public static void main(String[] args) {
        FileOutputStream fos=null;
        try {
            //如果没有这个文件,会自动创建一个
            //这种构造方法会将原文件清空,然后重新写入
             //fos = new FileOutputStream("JAVAse进阶/src/IO流/aa");

            //这个构造方法,以追加的方式在文件末尾写入,不会清空原文件内容。
            fos = new FileOutputStream("JAVAse进阶/src/IO流/aa",true);
             //开始写
            byte[] bytes = {97,98,99,100};
            //将byte全部写出
            fos.write(bytes);
            //将byte数组一部分写出 从下标0开始,取2个
            fos.write(bytes,0,2);
            //字符串
            String s = "我是一个中国人";
            //将字符串转换成byte数组。
            byte[] bytes1 = s.getBytes(StandardCharsets.UTF_8);
            //写
            fos.write(bytes1);
            //写完之后一定要刷新
            fos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (args != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

运行后文件末尾会多出:abcdab我是一个中国人

文件复制

使用FileInputStream+FileOutputStream完成文件的拷贝。拷贝的过程应该是一边读,一边写。
使用以上的字节流拷贝文件的时候,文件类型随意,万能的。什么样的文件都能拷贝。

public class 文件复制 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            //创建一个输入流对象
            fis= new FileInputStream("D:\\a剪辑\\完成视频\\123.mp4");
            //创建一个输出流对象
            fos = new FileOutputStream("D:\\123.mp4");

            //最核心 一边写 一边读
            byte[] bytes =new byte[1024*1024]; //1MB(一次最多拷贝1MB)
            int aa = 0;
            while ((aa= fis.read(bytes))!=-1){ //Fis.Read(bytes) :往bytes数组中读
                fos.write(bytes,0,aa);  // 然后从数组拿出来 一次写aa个,aa是写入数组的数量
            }

            //刷新 输出流最后要刷新
            fos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos == null) {
             // 分开try,不要一起try
             // 一起try的时候,其中一个异常,可能会影响另外一个流的关闭。
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

FileReader(读 字符)

FileReader :文件字符输入流。只能读取普通文本。
读取文本内容时,比较方便,快捷。

FileReader 和上面 FileInputStream(读 字节)的使用方法一样,直接照葫芦画瓢

public class FileReader{
    public static void main(String[] args) {
        FileReader fileReader =  null;
        try {
            //创建文件字符输入流
            fileReader = new FileReader("JAVAse进阶/src/IO流/aa");
            //开始读
            char [] chars = new char[4]; //一次读四个字符
            int red = 0;
            while ((red = fileReader.read(chars))!=-1){
                //使用String构造方法,将char转换为字符串,从0开始,到red结束,转换这么多
                //red返回的是读取字符数量。
                System.out.print(new String(chars,0,red));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileReader != null) {
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

FileWriter (写 字符)

FileWriter: 文件字符输出流,只能输出普通文本。

public class FileWriter{
    public static void main(String[] args) {
        FileWriter fileWriter = null;
        try {
            //创建文件字符流对象 清空原文内容在写入
            //fileWriter = new FileWriter("JAVAse进阶/src/IO流/aa");
            //加个ture 表示不清空原文内容,从后面追加
            fileWriter = new FileWriter("JAVAse进阶/src/IO流/aa",true);
            //创建一个char数组
            char[] chars = {'我','是','中','国','人'};
            //全部写出
            fileWriter.write(chars);
            //部分写出,下标从2开始,取三个
            fileWriter.write(chars,2,3);
            //直接传入一个String也是可以的
            fileWriter.write("我是中国人");

            //换行符
            fileWriter.write("\n");
            fileWriter.write("励志当一个程序员");


            //刷新  写出都要刷新
            fileWriter.flush();

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

    }
}

复制普通文本文件

使用FileReader, FileWriter进行拷贝的话,只能拷贝“普通文本”文件。

public class 复制普通文本文件 {
    public static void main(String[] args) {
        FileReader du = null;
        FileWriter xie = null;
        try {
            //读
            du = new FileReader("JAVAse进阶/src/IO流/aa");
            //写
            xie = new FileWriter("aa");
            //一边读一边写
            char [] chars = new char[1024*512];
            int aa = 0;
            //du.read(chars) 往chars数组中读
            while ((aa =du.read(chars) )!=-1){
                //读多少写多少
                xie.write(chars,0,aa);
            }
            //刷新
            xie.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (xie != null) {
                try {
                    xie.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (du != null) {
                try {
                    du.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。