【Java】IO流的混乱关系,看得我直呼绝绝子

本文涉及的产品
数据传输服务 DTS,数据同步 small 3个月
推荐场景:
数据库上云
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
数据传输服务 DTS,数据同步 1个月
简介: I表示input、O表示output表示输入输出流。流是一种抽象的概念,是对数据传输的总称,也就是数据在设备间传输称为流,流的本质是数据传输,流的本质是数据传输。

 目录

一、前言

二、IO流概述

三、字节流写数据

字节流写数据的三种方式:

字节流数据据

1.一次读一个字节

2.一次读一个数组

四、字符缓冲流

字符缓冲流写文件

字符缓冲流读数据


一、前言

这些奇奇怪怪的流在理解起来也是其奇怪怪的,用起来却真香┗|`O′|┛ 嗷~~

二、IO流概述

I表示input、O表示output表示输入输出流。

流是一种抽象的概念,是对数据传输的总称,也就是数据在设备间传输称为流,流的本质

是数据传输,流的本质是数据传输。

我们都知道,程序运行会加载到内存上。

image.png

image.gif

    • IO流就是用来处理设备间数据传输的问题的

    IO流的分类大致可以分为两种:

    ①按数据流向

      •      输入流:读数据
      •      输出流:写数据

      ②按数据类型分

        •      字节输入流;字节输出流
        •      字符输入流;字符输出流

        一般来说IO流是按照数据类型分的

        文本文件一般用字符流,其他用字节流

        字节流是万能流,可以用于任意类型的文件。

        三、字节流写数据

        ①InputStream:

          • 这个抽象类是表示输入字节流的所有类的超类。

          ②OutputStream:

            • 这个抽象类是表示字节输出流的所有类的超类。

            他们的子类都是以其父类作为子类名的后缀:


            image.gifimage.png


            image.gif

            因为他是一个抽象类,所以我们写、读数据一般都用他们的直接子类。

            FileOutputStream和FileInputStream,前者用于写数据,后者用于读数据。

            FileOutputStream(String name):创建文件输入流以指定的名称写入文件

            public class FileOutputDemo {
                public static void main(String[] args) throws IOException {
                    //创建字节输出流对象,这个子类都会抛出异常FileNotFoundException  
                    FileOutputStream fos=new FileOutputStream("E:\\MyTest\\kong.txt");
                    File f1=new File("E:\\MyTest\\kong.txt");
                    System.out.println(f1.createNewFile());
                    //write会抛出IOException异常,所以他所在得方法中得抛出异常throws也可以try..catch处理
                    fos.write(49);//1
                   fos.write(48); //0
                   fos.write(48);//0
                    byte arr[]=new byte[10];
                    fos.write(arr);
                    //释放资源
                    fos.close();
                }
            }

            image.gif

            E:\\MyTest\\kong.txt,这个表示我创建在E盘下的Mytest模块下得kong.txt目录,当文件

            已经存会创建失败(false),返回的是boolean类型

            创建对象做了三件事情:

              •        调用系统功能创建文件。
              •        创建字节输出流对象。
              •        让字节输出流指向创建好的文件。

              凡是涉及到IO操做创建的对象都得释放资源。

              字节流写数据的三种方式:

              image.png

              image.gif

              import java.io.*;
              public class FileOutputStreamDemo02 {
                  public static void main(String[] args) throws IOException {
                      //创建输入流对象
                      FileOutputStream fos=new FileOutputStream("E:\\MyTest\\kong03.txt");
                      FileOutputStream fos1=new FileOutputStream(new File("E:\\MyTest\\kong03.txt"));
                      //上面两种方式等价
                          //第一种方式写
                      fos.write(97); fos.write(98); fos.write(99);
                         //第二种方式写
                      byte[]bys={97,98,99,100};//abcd
                      fos.write(bys);
                         //第三种方式写
                      byte[]bys1="abcd".getBytes();
                      fos.write(bys1, 1, 3);//bcd写在文件
                      //释放资源
                      fos.close();
                  }
              }

              image.gif

              image.png

              image.gif

              字节流写数据的两个小问题:

              有上面的操作可知,我们不难发现这写入的数据没有换行,这看着十分不舒服。

              ①字节流输入数据换行问题:

                • windows操作系统下:\r\n
                • Linux:\n
                • mac:\r

                只需在写数据时加入对应的即可实现换行

                ②字节流写数据如何追加的问题

                只需要在创建指定路径后加true即可。

                public FileOutputSteam(String name,boolean append)

                image.gif

                import java.io.FileOutputStream;
                import java.io.IOException;
                public class FileTextZJ {
                    public static void main(String[] args) throws IOException {
                        FileOutputStream fos =new FileOutputStream("E:\\MyTest\\kong04.txt",true);
                        for (int i=0;i<5;i++){
                            fos.write("hello\r\n".getBytes());
                        }
                        fos.close();
                    }
                }

                image.gif

                下面时运行两次的结果:,达到了我们像要的追加效果。

                image.png

                image.gif

                字节流数据据

                1.一次读一个字节

                FileInputStream(String name)//写出从哪里读取

                image.gif

                没数据到达文件末尾时,返回-1,所以只需根据返回值即可

                public class FileInputStreamDemo{
                   public static void main(String [] args) throw IoException{
                     FileInputStream fis=new FileInputStream("E:MyByte\\kong02.txt");
                     int by;
                     while(by=fis.read()!=-1){
                       System.out.println((char)by);
                     }
                     fis.close();
                   }
                }

                image.gif

                2.一次读一个数组

                import java.io.FileInputStream;
                import java.io.IOException;
                public class FileInputStreamDemo01 {
                    public static void main(String[] args) throws IOException {
                        FileInputStream fis=new FileInputStream("E:\\MyTest\\kong1.txt");
                        byte[]bys=new byte[1024];
                        int len;
                        while((len=fis.read())!=-1){
                            System.out.println(new String(bys,0,len));
                        }
                        fis.close();
                    }
                }

                image.gif

                四、字符缓冲流

                  • BufferedWriter
                  • BufferedReader

                  image.gif

                  缓冲流的参数需要一个FileWriter或FileReader对象

                  字符缓冲流写文件

                  import java.io.BufferedWriter;
                  import java.io.FileWriter;
                  import java.io.IOException;
                  public class BufferedWriterDemo1 {
                      public static void main(String[] args) throws IOException {
                          BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\MyText\\KongChao.txt"));
                          bw.write("hello\r\n");
                          bw.write("world\r\n");
                          bw.close();
                      }
                  }

                  image.gif

                  字符缓冲流读数据

                  public class BufferedWriterDemo {
                      public static void main(String[] args) throws IOException {
                          BufferedReader br=new BufferedReader(new FileReader("E:\\MyTest\\kong.txt"));
                          int ch;
                          while((ch=br.read())!=-1){
                              System.out.print((char)ch);
                          }
                          br.close();
                      }
                  }

                  image.gif

                  字符缓冲流特有功能

                    • BufferedWriter:
                    void newLine();//相当于换行

                    image.gif

                      • BufferedReader:
                      public String readLine():读一行文件,不包括换行符、和终止符,若流已经到文件尾部,则为null

                      image.gif

                      将使用特有方法,输存结合

                      import java.io.*;
                      public class BufferedWriterDemo1 {
                          public static void main(String[] args) throws IOException {
                        //创建字符输入流
                              BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\MyTest\\KongChao.txt"));
                        //创建字符输出流      
                              BufferedReader br= new BufferedReader(new FileReader("E:\\MyTest\\copy.txt"));
                              String line;
                              while((line=br.readLine())!=null){
                                  bw.write(line);bw.newLine();
                                  bw.flush();//刷新到文件上
                              }
                              //关闭资源
                              bw.close();
                              br.close();
                      }  }

                      image.gif


                      相关实践学习
                      如何在云端创建MySQL数据库
                      开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
                      Sqoop 企业级大数据迁移方案实战
                      Sqoop是一个用于在Hadoop和关系数据库服务器之间传输数据的工具。它用于从关系数据库(如MySQL,Oracle)导入数据到Hadoop HDFS,并从Hadoop文件系统导出到关系数据库。 本课程主要讲解了Sqoop的设计思想及原理、部署安装及配置、详细具体的使用方法技巧与实操案例、企业级任务管理等。结合日常工作实践,培养解决实际问题的能力。本课程由黑马程序员提供。
                      目录
                      相关文章
                      |
                      小程序 Java
                      Java 8 排序的 10 个姿势,太秀了吧!同事直呼看不懂。。
                      Java 8 排序的 10 个姿势,太秀了吧!同事直呼看不懂。。
                      209 0
                      Java 8 排序的 10 个姿势,太秀了吧!同事直呼看不懂。。
                      |
                      前端开发 安全 Java
                      再见,xShell,自己用Java撸一个Web版的,网友直呼:666
                      再见,xShell,自己用Java撸一个Web版的,网友直呼:666
                      444 0
                      再见,xShell,自己用Java撸一个Web版的,网友直呼:666
                      |
                      JSON 前端开发 Java
                      我用 Java 8 写了一段逻辑,同事直呼看不懂,你试试看。。
                      我用 Java 8 写了一段逻辑,同事直呼看不懂,你试试看。。
                      163 0
                      我用 Java 8 写了一段逻辑,同事直呼看不懂,你试试看。。
                      |
                      存储 Java Unix
                      Java IO 知识点总结和盘点,看完后直呼很哇塞(2)
                      Java IO 知识点总结和盘点,看完后直呼很哇塞
                      377 0
                      Java IO 知识点总结和盘点,看完后直呼很哇塞(2)
                      |
                      Java 程序员
                      Java IO 知识点总结和盘点,看完后直呼很哇塞(1)
                      Java IO 知识点总结和盘点,看完后直呼很哇塞
                      182 0
                      Java IO 知识点总结和盘点,看完后直呼很哇塞(1)
                      |
                      11天前
                      |
                      安全 Java 测试技术
                      Java并行流陷阱:为什么指定线程池可能是个坏主意
                      本文探讨了Java并行流的使用陷阱,尤其是指定线程池的问题。文章分析了并行流的设计思想,指出了指定线程池的弊端,并提供了使用CompletableFuture等替代方案。同时,介绍了Parallel Collector库在处理阻塞任务时的优势和特点。
                      |
                      20天前
                      |
                      安全 Java
                      java 中 i++ 到底是否线程安全?
                      本文通过实例探讨了 `i++` 在多线程环境下的线程安全性问题。首先,使用 100 个线程分别执行 10000 次 `i++` 操作,发现最终结果小于预期的 1000000,证明 `i++` 是线程不安全的。接着,介绍了两种解决方法:使用 `synchronized` 关键字加锁和使用 `AtomicInteger` 类。其中,`AtomicInteger` 通过 `CAS` 操作实现了高效的线程安全。最后,通过分析字节码和源码,解释了 `i++` 为何线程不安全以及 `AtomicInteger` 如何保证线程安全。
                      java 中 i++ 到底是否线程安全?
                      |
                      8天前
                      |
                      安全 Java 开发者
                      深入解读JAVA多线程:wait()、notify()、notifyAll()的奥秘
                      在Java多线程编程中,`wait()`、`notify()`和`notifyAll()`方法是实现线程间通信和同步的关键机制。这些方法定义在`java.lang.Object`类中,每个Java对象都可以作为线程间通信的媒介。本文将详细解析这三个方法的使用方法和最佳实践,帮助开发者更高效地进行多线程编程。 示例代码展示了如何在同步方法中使用这些方法,确保线程安全和高效的通信。
                      28 9
                      |
                      11天前
                      |
                      存储 安全 Java
                      Java多线程编程的艺术:从基础到实践####
                      本文深入探讨了Java多线程编程的核心概念、应用场景及其实现方式,旨在帮助开发者理解并掌握多线程编程的基本技能。文章首先概述了多线程的重要性和常见挑战,随后详细介绍了Java中创建和管理线程的两种主要方式:继承Thread类与实现Runnable接口。通过实例代码,本文展示了如何正确启动、运行及同步线程,以及如何处理线程间的通信与协作问题。最后,文章总结了多线程编程的最佳实践,为读者在实际项目中应用多线程技术提供了宝贵的参考。 ####
                      |
                      7天前
                      |
                      监控 安全 Java
                      Java中的多线程编程:从入门到实践####
                      本文将深入浅出地探讨Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的摘要形式,本文将以一个简短的代码示例作为开篇,直接展示多线程的魅力,随后再详细解析其背后的原理与实现方式,旨在帮助读者快速理解并掌握Java多线程编程的基本技能。 ```java // 简单的多线程示例:创建两个线程,分别打印不同的消息 public class SimpleMultithreading { public static void main(String[] args) { Thread thread1 = new Thread(() -> System.out.prin