本人小白一枚,欢迎大家一起讨论学习,如有错误,还望大家指教。

简述:

IO(Input Output)流用来处理设备之间的数据传输,Java对数据的操作是通过流的方式。Java用于操作流对象都在IO包中,流按操作数据分为两种:字节流字符流。流按流向分为两种:输入流输出流

Java中的字节流处理的最基本单位为单个字节,它通常用来处理二进制数据,如媒体文件

Java中的字符流处理的最基本单位为Unicode码元(大小2字节),它通常用来处理文本数据

java中什么是输入流 java字符输入流是什么_输入流


对于刚开始学习JavaIO流,我对输入输出流的概念总是混淆,后来看了看大家对他们的理解,我似乎也明朗了不少。大概的意思就是如下,这里我们把程序当做第一人称来进行理解。

将数据从外存中读取到内存中的称为输入流。

将数据从内存中写入到外存中的称为输出流。

java中什么是输入流 java字符输入流是什么_字符流_02

字符流

FileWriter(File file, boolean append) :根据给定的 File 对象构造一个 FileWriter 对象。该方法传递一个true参数,代表不覆盖已有的文件。并在已有文件的末尾处进行数据续写,如果没有该文件,则创建该文件。

字符流两个基类:
Reader(字符输入流) Writer (字符输出流)
输出流案例

public static void main(String[] args) {
        FileWriter fileWriter = null;
        try {
            // 创建一个FileWriter对象,初始化就要必须明确被操作的文件。
            // 如果该目录下已有同名文件,将被覆盖。
            fileWriter = new FileWriter("demo.txt");
            // 将字符串写入流中,我们需要流对象中的缓冲数据,即fileWriter.flush(),如果不刷新流,数据将不会写入到文件
            fileWriter.write("喜气洋洋!!!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileWriter != null) {
                try {
                    // 关闭流资源,会自动刷新流。关闭与刷新区别:flush刷新后流还未关闭,可以继续使用,close反之。
                    fileWriter.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

操作成功,文件存在并成功写入特定字符串

java中什么是输入流 java字符输入流是什么_数据_03


输入流案例

读取输入流的两种方式

public static void main(String[] args) {
        FileReader fileReader = null;
        try {
            fileReader = new FileReader("demo.txt");
            // 一个一个字符读取
            int ch = 0;
            while((ch = fileReader.read()) != -1) {
                System.out.print((char) ch);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileReader != null) {
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
public static void main(String[] args) {
        FileReader fileReader = null;
        try {
            fileReader = new FileReader("demo.txt");
            // 通过字符数据进行读取
            char[] chars = new char[1024];
            int num =  0;
            while((num = fileReader.read(chars)) != -1) {
                System.out.print(new String(chars, 0, num));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileReader != null) {
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

喜气洋洋!!!

字符流缓冲区

简述:缓冲区的出现提高了对数据的读写效率。对应类:BufferedWriterBufferedReader。缓冲区要结合流才可以使用,在流的基础上对流的功能进行了增强。
对缓冲区的简单理解:在对文件进行读写操作时,如果是边读边写就会很慢,也伤硬盘。而缓冲区就是内存里的一块区域,把数据先存内存里,然后一次性写入,类似数据库的批量操作,这样效率比较高。
字符读取流缓冲区:该缓冲区提供了一个一次读一行的方法 readLine(),方便于对文本数据的获取。当返回null时,表示读到文件末尾。readLine方法返回的时候只返回回车符之前的数据内容。并不返回回车符,返回值String

public static void main(String[] args) {
        FileWriter fileWriter = null;
        BufferedWriter bufferedWriter = null;
        FileReader fileReader = null;
        BufferedReader bufferedReader = null;
        try {
            fileWriter = new FileWriter("writer.txt");
            bufferedWriter = new BufferedWriter(fileWriter);
            for (int i = 1;i <= 5;i++) {
                bufferedWriter.write("abcdefg" + i);
                bufferedWriter.newLine();
            }
            bufferedWriter.flush();
            fileReader = new FileReader("writer.txt");
            bufferedReader = new BufferedReader(fileReader);
            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                System.out.println(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bufferedWriter != null) {
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fileWriter != null) {
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fileReader != null) {
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

对于我们学习上面的字符流和字符缓冲区,我们可以扩展一下设计模式— 装饰设计模式
当我们想要对已有的对象功能进行增强时,可以定义类,将已有的对象传入,基于已有的功能,并提供加强的功能。那么自定义的类就称为装饰类。装饰类通常会通过构造器接收被装饰的对象,并基于被装饰对象的功能,提供更强的功能。例如,BufferedReader类中的readLine()就是对FileReader类中read()方法加强,该方法就用到了这种设计模式。

字节流

字节流:InputStream字节输入流,OutputStream字节输出流
字节缓冲区:BufferedInputStreamBufferedOutputStream案例:复制一张图片

public static void main(String[] args) {
        // 字节输入流
        FileInputStream inputStream = null;
        // 字节输入缓冲区
        BufferedInputStream bufferedInputStream = null;
        // 字节输出流
        FileOutputStream outputStream = null;
        // 字节输出缓冲区
        BufferedOutputStream bufferedOutputStream = null;
        try {
            // 字节流一共有三种取出方式,除了一个一个字节取出和字节数组方式外,还有另一种方式
            inputStream = new FileInputStream("test.jpg");
            bufferedInputStream = new BufferedInputStream(inputStream);
            outputStream = new FileOutputStream("demo.jpg");
            bufferedOutputStream = new BufferedOutputStream(outputStream);
            // 定义一个刚刚好的缓冲区,不用在进行循环了
            byte[] bytes = new byte[bufferedInputStream.available()];
            bufferedInputStream.read(bytes);
            bufferedOutputStream.write(bytes);
            bufferedOutputStream.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bufferedInputStream != null) {
                try {
                    bufferedInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedOutputStream != null) {
                try {
                    bufferedOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }