IO流【Java中IO的四大抽象类、常用流详解 、 缓冲字节流、 文件字符流、缓冲字符流】(二)-全面详解(学习总结---从入门到深化)

简介: IO流【Java中IO的四大抽象类、常用流详解 、 缓冲字节流、 文件字符流、缓冲字符流】(二)-全面详解(学习总结---从入门到深化)

Java中IO的四大抽象类


InputStream/OutputStream和Reader/writer类是所有IO流类的抽 象父类,我们有必要简单了解一下这个四个抽象类的作用。然后, 通过它们具体的子类熟悉相关的用法。


InputStream


此抽象类是表示字节输入流的所有类的父类。InputSteam是一个抽 象类,它不可以实例化。 数据的读取需要由它的子类来实现。根据 节点的不同,它派生了不同的节点流子类 。 继承自InputSteam的流都是用于向程序中输入数据,且数据的单位 为字节(8 bit)。


常用方法:


OutputStream


此抽象类是表示字节输出流的所有类的父类。输出流接收输出字节 并将这些字节发送到某个目的地。


常用方法:


Reader


Reader用于读取的字符流抽象类,数据单位为字符。


Writer


Writer用于输出的字符流抽象类,数据单位为字符。


常用流详解


文件字节流


FileInputStream   通过字节的方式读取文件,适合读取所有类型的文 件(图像、视频、文本文件等)。

FileOutputStream 通过字节的方式写数据到文件中,适合所有类型 的文件(图像、视频、文本文件等)。


FileInputStream文件输入字节流

public class TestFileInputStream {
    public static void main(String[] args) {
        //使用try-with-resource方式关闭资源。
        //在try中打开资源,不需要在代码中添加finally块关闭资源。
        try(FileInputStream fis = new FileInputStream("d:/a.txt");){
            StringBuilder sb = new StringBuilder();
            int temp=0;
            while((temp = fis.read()) != -1)
           {
                sb.append((char) temp);
           }
              System.out.println(sb);
       }catch(Exception e){
            e.printStackTrace();
       }
   }


FileOutputStream文件输出字节流

public class TestFileOutputStream {
    public static void main(String[] args) {
        String str = "Old Lu";
        // true表示内容会追加到文件末尾;false表示重写整个文件内容。
        try(FileOutputStream fos = new
             FileOutputStream("d:/a.txt",true)){
            //将整个字节数组写入到文件中。
            fos.write(str.getBytes());
           //将数据从内存中写入到磁盘中。
           fos.flush();
       }catch (IOException e){
            e.printStackTrace();
       }
   }
}


通过字节缓冲区提高读写效率


通过创建一个指定长度的字节数组作为缓冲区,以此来提高IO流的 读写效率。该方式适用于读取较大文件时的缓冲区定义。注意:缓 冲区的长度一定是2的整数幂。一般情况下1024长度较为合适。

public class TestFileByteBuffer{
    public static void main(String[] args) {
        long time1 = System.currentTimeMillis();
        copyFile("d:/1.jpg", "d:/2.jpg");
        long time2 = System.currentTimeMillis();
        System.out.println(time2 - time1);
   }
    /**
     *
     * @param src 源文件
     * @param desc 目标文件
     */
    public static void copyFile(String src,String desc){
       //“后开的先关闭!”按照他们被创建顺序的逆序来关闭
       try(FileInputStream fis = new FileInputStream(src);
           FileOutputStream fos = new FileOutputStream(desc)){
           //创建一个缓冲区,提高读写效率
            byte[] buffer = new byte[1024];
            int temp = 0;
            while ((temp = fis.read(buffer)) != -1){
          //将缓存数组中的数据写入文件中,注意:写入的是读取的真实长度;
            fos.write(buffer,0,temp);
           }
            //将数据从内存中写入到磁盘中。
           fos.flush();
       }
        catch (IOException e) {
            e.printStackTrace();
       }
   }
}


注意 在使用字节缓冲区时,我们需要注意:


1、为了减少对硬盘的读写次数,提高效率,通常设置缓存数组。相应地,读取时使用的方法 为:read(byte[] b);写入时的方法为:write(byte[ ] b, int off, int length)

2、程序中如果遇到多个流,每个流都要单独关闭,防止其中一个流出现异常后导致其他流无法 关闭的情况。


缓冲字节流


Java缓冲流本身并不具有IO流的读取与写入功能,只是在别的流 (节点流或其他处理流)上加上缓冲功能提高效率,就像是把别的 流包装起来一样,因此缓冲流是一种处理流(包装流)。 BufferedInputStream和BufferedOutputStream这两个流是缓冲 字节流,通过内部缓存数组来提高操作流的效率。


使用缓冲流实现文件的高效率复制


下面我们通过两种方式(普通文件字节流与缓冲文件字节流)实现 一个文件的复制,来体会一下缓冲流的好处。

public class TestFileBufferStream {
    public static void main(String[] args) {
        long time1 = System.currentTimeMillis();
        copyFile("d:/1.jpg","d:/2.jpg");
        long time2 = System.currentTimeMillis();
        System.out.println(time2 - time1);
   }
    public static void copyFile(String source,String destination){
            //实例化节点流
        try(FileInputStream fis = new FileInputStream(source);
            FileOutputStream fos = new FileOutputStream(destination);
            //实例化处理流
            BufferedInputStream bis = new BufferedInputStream(fis);
            BufferedOutputStream bos = new BufferedOutputStream(fos)){
            int temp = 0;
            while ((temp = bis.read()) !=-1){
                bos.write(temp);
           }
            bos.flush();
       }catch(IOException e){
            e.printStackTrace();
       }
   }
}


注意


1、在关闭流时,应该先关闭最外层的包装流,即“后开的先关闭”。

2、缓存区的大小默认是8192字节,也可以使用其它的构造方法自己指定大小。


文件字符流


前面介绍的文件字节流可以处理所有的文件,如果我们处理的是文 本文件,也可以使用文件字符流,它以字符为单位进行操作。


文件字符输入流

public class TestFileReader {
    public static void main(String[] args) {
        //创建文件字符输入流对象
        try(FileReader fr = new FileReader("d:/a.txt")){
            StringBuilder sb = new StringBuilder();
        //读取文件
           int temp = 0;
           while((temp = fr.read()) != -1){
               sb.append((char)temp);
           }
            System.out.println(sb);
       }catch (IOException e){
            e.printStackTrace();
       }
   }
}


文件字符输出流

public class TestFileWriter {
    public static void main(String[] args) {
        //创建文件字符输出流对象
        try(FileWriter fw = new FileWriter("d:/aa.txt")){
            fw.write("您好尚\r\n");
            fw.write("您好Old Lu\r\n");
            fw.flush();
       }catch (IOException e){
            e.printStackTrace();
       }
   }
}


缓冲字符流


BufferedReader/BufferedWriter增加了缓存机制,大大提高了读 写文本文件的效率。


字符输入缓冲流


BufferedReader是针对字符输入流的缓冲流对象,提供了更方便的 按行读取的方法:readLine(); 在使用字符流读取文本文件时,我们 可以使用该方法以行为单位进行读取。

public class TestBufferedReader {
    public static void main(String[] args) {
            //创建文件字符输入流对象
        try(FileReader fr = new FileReader("d:/aa.txt");
            //创建字符缓冲处理流。缓冲区默认大小为8192个字符。
            BufferedReader br = new BufferedReader(fr)){
            //操作流
            String temp = "";
            //readLine():读取一行文本。
            while((temp = br.readLine()) != null){
                System.out.println(temp);
           }
       }catch(IOException e){
            e.printStackTrace();
       }
   }
}


字符输出缓冲流


BufferedWriter是针对字符输出流的缓冲流对象,在字符输出缓冲 流中可以使用newLine();方法实现换行处理。

public class TestBufferedWriter {
    public static void main(String[] args) {
  //创建文件字符输出流对象
        try(FileWriter fw = new FileWriter("d:/sxt.txt");
            //创建字符输出缓冲流对象
            BufferedWriter bw = new BufferedWriter(fw)){
            //操作缓冲流
            bw.write("您好尚像素");
            bw.write("您好Oldlu");
            //换行
            bw.newLine();
            bw.write("何以解忧");
            bw.newLine();
            bw.write("唯有学堂");
            bw.flush();
       }catch (IOException e){
            e.printStackTrace();
       }
   }
}


注意


readLine()方法是BufferedReader的方法,可以对文本文件进行更加方便的读取操作。 newLine()方法BufferedWriter的方法,可以使用newLine()方法换行。

 

为文件中的内容添加行号

public class TestLineNumber {
    public static void main(String[] args) {
            //创建字符输入缓冲流与文件字符输入流
            try(BufferedReader br = new BufferedReader(new FileReader("d:/sxt.txt"));
            //创建字符输出缓冲流与文件字符输出流
            BufferedWriter bw = new BufferedWriter(new FileWriter("d:/sxt2.txt"))){
            String temp ="";
            //定义序号变量
            int i = 1;
            while((temp = br.readLine()) != null){
                //将读取到的内容添加序号,并输出到指定文件中。
                bw.write(i+","+temp);
                //换行处理
                bw.newLine();
                //序号变量累加
                i++;
           }
            //刷新
            bw.flush();
       }catch(IOException e){
            e.printStackTrace();
       }
   }
}


目录
相关文章
|
5天前
|
Java
Java中的抽象类:深入了解抽象类的概念和用法
Java中的抽象类是一种不能实例化的特殊类,常作为其他类的父类模板,定义子类行为和属性。抽象类包含抽象方法(无实现)和非抽象方法。定义抽象类用`abstract`关键字,子类继承并实现抽象方法。抽象类适用于定义通用模板、复用代码和强制子类实现特定方法。优点是提供抽象模板和代码复用,缺点是限制继承灵活性和增加类复杂性。与接口相比,抽象类可包含成员变量和单继承。使用时注意设计合理的抽象类结构,谨慎使用抽象方法,并遵循命名规范。抽象类是提高代码质量的重要工具。
23 1
|
25天前
|
缓存 Linux API
文件IO和标准IO的区别
文件IO和标准IO的区别
19 2
|
26天前
|
存储 Java 数据处理
C4.
|
1月前
|
Java
Java抽象类
Java抽象类
C4.
15 0
|
1天前
|
存储 固态存储 Java
文件IO讲解
文件IO讲解
10 0
|
5天前
|
Java 关系型数据库 MySQL
大厂面试题详解:Java抽象类与接口的概念及区别
字节跳动大厂面试题详解:Java抽象类与接口的概念及区别
27 0
|
14天前
|
关系型数据库 Java 开发工具
Java入门高频考查基础知识9(15问万字参考答案)
本文探讨了Spring Cloud的工作原理,包括注册中心的心跳机制、服务发现机制,以及Eureka默认的负载均衡策略。同时,概述了Spring Boot中常用的注解及其实现方式,并深入讨论了Spring事务的注解、回滚条件、传播性和隔离级别。文章还介绍了MySQL的存储引擎及其区别,特别关注了InnoDB如何实现MySQL的事务处理。此外,本文还详细探讨了MySQL索引,包括B+树的原理和设计索引的方法。最后,比较了Git和SVN的区别,并介绍了Git命令的底层原理及流程。
26 0
Java入门高频考查基础知识9(15问万字参考答案)
|
14天前
|
存储 缓存 算法
Java入门高频考查基础知识4(字节跳动面试题18题2.5万字参考答案)
最重要的是保持自信和冷静。提前准备,并对自己的知识和经验有自信,这样您就能在面试中展现出最佳的表现。祝您面试顺利!Java 是一种广泛使用的面向对象编程语言,在软件开发领域有着重要的地位。Java 提供了丰富的库和强大的特性,适用于多种应用场景,包括企业应用、移动应用、嵌入式系统等。下是几个面试技巧:复习核心概念、熟悉常见问题、编码实践、项目经验准备、注意优缺点、积极参与互动、准备好问题问对方和知其所以然等,多准备最好轻松能举一反三。
45 0
Java入门高频考查基础知识4(字节跳动面试题18题2.5万字参考答案)
|
14天前
|
存储 算法 JavaScript
Java入门高频考查算法逻辑基础知识3-编程篇(超详细18题1.8万字参考编程实现)
解决这类问题时,建议采取下面的步骤: 理解数学原理:确保你懂得基本的数学公式和法则,这对于制定解决方案至关重要。 优化算法:了解时间复杂度和空间复杂度,并寻找优化的机会。特别注意避免不必要的重复计算。 代码实践:多编写实践代码,并确保你的代码是高效、清晰且稳健的。 错误检查和测试:要为你的代码编写测试案例,测试标准的、边缘情况以及异常输入。 进行复杂问题简化:面对复杂的问题时,先尝试简化问题,然后逐步分析和解决。 沟通和解释:在编写代码的时候清晰地沟通你的思路,不仅要写出正确的代码,还要能向面试官解释你的
32 0
|
14天前
|
存储 Java 编译器
Java入门高频考查基础知识2(超详细28题2.5万字答案)
多态是面向对象编程中的一个重要概念,它允许不同类的对象对同一消息作出不同的响应。在具体实现上,多态允许一个父类的引用指向其子类的对象,并根据实际指向的对象的类型来调用相应的方法。在 Java 中,多态可以通过以下几种方式实现:在同一个类中,方法名相同,但形参列表不同,实现了多态。子类可以重写(覆盖)其父类的方法,实现多态。在父类引用中调用该方法时,根据实际指向的子类对象的类型来调用相应的方法实现。
36 0