Java基础--IO流

File类

File类的介绍

java.io.File类
文件和目录路径名的抽象表示形式。
File类封装了计算机中文件和文件夹,我们可以通过File类中的方法来操作计算机中的文件和文件夹(目录)
  我们可以使用File类中的方法创建文件|文件夹
  我们可以使用File类中的方法删除文件|文件夹
  我们可以使用File类中的方法获取文件|文件夹路径
  我们可以使用File类中的方法遍历文件夹
  我们可以使用File类中的方法获取文件的大小(字节)

File类的静态成员变量

File类中的静态成员变量

static String pathSeparator 与系统有关的路径分隔符,为了方便,它被表示为一个字符串。
static char pathSeparatorChar 与系统有关的路径分隔符。
static String separator 与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。
static char separatorChar 与系统有关的默认名称分隔符。  

File类是一个与系统无关的类,任何的操作系统都可以使用File类中的方法和变量

路径

路径:操作计算机文件和文件夹的路径
分类:
 1.绝对路径:以盘符(c:|C:,d:,e:)开始的路径(唯一)
  c:\a.txt
  d:\aaa\bbb\ccc
  D:\Work_idea\EE24\day20
 2.相对路径:相当于我们当前项目的根目录而言,我们使用项目的根目录作为路径,可以省略书写
  比如我的当前项目的根目录:D:\javaEE
  绝对路径: D:\javaEE\day10 D:\javaEE\day10\a.txt
  相对路径: 可以省略项目的根目录,java会自动给我们在路径的前边添加上项目的根目录

	D:\\javaEE\\day20(绝对)==>day20(相对)
        D:\\javaEE\\day20\\a.txt(绝对)==>day20\\a.txt(相对) 
        d:\\aaa\\bbb\\ccc和项目没有关系,是不能省略的
        aa\\bb\\cc\\c.txt(相对)==>D:\\javaEE\\aa\\bb\\cc\\c.txt(绝对)

注意:
1.路径是不区分大小写的 d:\a.txt D:\A.TXT
2.如果要使用反斜杠()作为文件|文件夹的分隔符,需要写两个(\),一个反斜杠本身是转义字符,有特殊含义
3.在java程序中,也可以使用一个正斜杠(/)作为文件|文件夹的分割符号 d:\a.txt d:/a.txt

File的构造方法

        File(String pathname)
          通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
        参数:
           String pathname:文件|文件夹的路径名称
        注意:
            1.参数传递的路径可以是绝对路径,也可以是相对路径
            2.参数传递的路径可以是以文件结尾的,也可以是以文件夹结尾的
            3.参数传递的路径可以是真实存在的,也可以是不存在的;构造方法仅仅是把字符串的路径,封装为File对象,不检查路径的真实情况
        File(String parent, String child) 根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。
        参数:把构造方法参数路径分割为了两部分
           String parent:父路径
           String child:子路径
        好处:
            父路径和子路径分别使用不同的路径,组装为一个新的路径,使用起来更加灵活
        File(File parent, String child) 根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。
        参数:把构造方法参数路径分割为了两部分
           File parent:父路径
           String child:子路径
        好处:
           1.父路径和子路径分别使用不同的路径,组装为一个新的路径,使用起来更加灵活
           2.父路径是File类型,可以使用File类的方法对父路径进行一些操作,在和子路径组成一个新的File

File类的成员方法_获取功能的方法

        public String getAbsolutePath() :返回此File的绝对路径名字符串。
        public String getPath() :将此File转换为路径名字符串。
        public String getName() :返回由此File表示的文件或目录的名称。
        public long length() :返回由此File表示的文件的长度。 不能获取目录的长度。
        public String getAbsolutePath() :返回此File的绝对路径名字符串。
            获取构造方法中传递的路径
                传递的路径是绝对的,就直接返回这个绝对路径
                传递的路径是相对的,会在相对路径的前边添加上项目的根目录在返回
        public String getPath() :将此File转换为路径名字符串。
             获取构造方法中传递的路径
                传递的路径是绝对的,就返回这个绝对路径
                传递的路径是相对的,就返回这个相对路径
        File类重写了Object类的toString方法
        toString方法的底层源码:
           public String toString() {
                return getPath();
            }
        public String getName() :返回由此File表示的文件或目录的名称。
            获取构造方法中路径末尾部分的名字(文件名称|文件夹名称)
        public long length() :返回由此File表示的文件的长度。 不能获取目录的长度。
            获取文件的大小,单位是字节
        注意:
            1.length方法只能获取文件的大小,不能获取文件夹的大小(文件夹是没有大小概念的)
            2.length方法获取是构造方法中传递文件路径指定的文件大小
            3.如果传递路径路径不存在,那么此方法返回0

文件的大小和文件的占用空间

计算机的硬盘默认是以4KB(4096个字节)作为一个最小单位进行分割的,会把计算机的硬盘分成无数多个小的4KB大小的空间.如果我们往硬盘中存储数据,数据没有4096个字节,也会占用4KB大小的空间.

File类的成员方法_判断功能的方法

    File类的成员方法_判断功能的方法(重点)
        public boolean exists() :此File表示的文件或目录是否实际存在。
        public boolean isDirectory() :此File表示的是否为目录。
        public boolean isFile() :此File表示的是否为文件。
        public boolean exists() :判断构造方法中传递的路径是否存在
            存在:返回true
            不存在:返回false
        public boolean isDirectory():判断构造方法中传递的路径是否是以文件夹结尾
            是文件夹结尾:返回true
            不是文件夹结尾:返回false
        public boolean isFile() :判断构造方法中传递的路径是否是以文件结尾
            是文件结尾:返回true
            不是文件结尾:返回false
        注意:
            1.路径必须是存在的,才能判断路径是以文件还是文件夹结尾;否则没有意义,否会返回false
            2.计算机中只有文件和文件夹,所以两个方法互斥

File类的成员方法_创建删除功能的方法

    File类的成员方法_创建删除功能的方法(重点)
        public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
        public boolean mkdir() :创建由此File表示的目录。
        public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录。
        public boolean delete() :删除由此File表示的文件或目录。
        public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
        作用:用于创建一个新的空白文件
        返回值:boolean
            文件不存在,创建成功,返回true
            文件存在,不会创建新的,返回false(不会覆盖)
        注意:
            1.此方法只能创建文件,不能创建文件夹
            2.创建文件的名字和路径在构造方法中给出
            3.构造方法中写的文件的路径必须是存在的,否则会抛出异常
            4.有些操作系统,c盘是没有权限创建文件的,会抛出拒绝访问异常
        public boolean mkdir() :只能创建单级文件夹
        public boolean mkdirs() :既能创建单级文件夹,又能创建多级文件夹
        返回值:boolean
            文件夹不存在,创建成功,返回true
            文件夹存在,不会创建返回false;构造方法中传递路径不存在,返回false
        注意:
            1.创建文件夹的名称和路径在构造方法中给出
            2.此方法只能创建文件夹,不能创建文件
        public boolean delete() 删除构造方法中指定的文件|文件夹
        返回值:boolean
            构造方法中路径存在,删除文件|文件夹,返回true
            构造方法中路径不存在或者文件夹中有内容,不会删除,返回false
        注意:
            此删除方法,不走回收站,直接在硬盘上删除,需要谨慎

File类的成员方法_目录遍历的方法

    File类的成员方法_目录遍历的方法(重点)
        public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。
            遍历目录(文件夹),获取目录中每一个文件|文件夹的名称,把多个名称存储到一个String类型的数组中返回
        public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。
             遍历目录(文件夹),获取目录中每一个文件|文件夹,把文件|文件夹封装为File对象,多个File对象存储到一个File类型的数组中返回
    注意:
        1.遍历目录的路径,在构造方法中给出
        2.遍历目录的路径是必须存在的,否则会抛出空指针异常
        3.这两个方法只能遍历目录,不能遍历文件,否则会抛出空指针异常

递归

递归的概述

递归:方法自己调用自己
递归的分类:
  1.直接递归

            public void a(){
                a();
            }

  2.间接递归

            public void a(){
                b();
            }
            public void b(){
                a();
            }

递归的注意事项:
  1.递归必须有结束的条件,保证递归可以停止下来,否则会抛出内存溢出的错误
  2.递归有结束的条件,但是递归的次数也不能太多,否则会抛出内存溢出的错误
  3.构造方法禁止递归
什么时候使用递归:
  当我们频繁的调用一个方法,方法的主体不变,每次调用方法的参数改变,就可以使用递归

递归求1-n的累加和以及阶乘

//1-n的累加和
private static int sumOfN(int n) {
    if(n == 1){
        return 1;
    }
    return n + sumOfN(n-1);
}
//阶乘
private static int jiecheng(int n) {
    if(n == 1){
        return 1;
    }
    return n * jiecheng(n-1);

递归遍历多级文件夹

private static void getAllFile(File file) {
    File[] files = file.listFiles();
    for (File f : files) {
        if (f.isFile()) {
            System.out.println(f.getName());
        }else{
            getAllFile(f);
        }
    }
}

IO流

概述

IO流:
  I:Input,输入.将硬盘中的数据读取到内存中.
  O:Output,输出.将内存中的数据写到硬盘中.
  流:可以看成管道,数据可以通过流进行传输.
ps:输入和输出都是以内存为参照物的
IO流用于数据传输,比如上传,下载,文件拷贝.

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

一切皆为字节
硬盘中的一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存(计算机只能识别0和1),都一个一个的字节(1个字节=8比特位),那么传输时一样如此。所以,字节流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据(1,0)。

字节流

字节输出流

介绍

OutputStream是字节输出流,用来写,可以将Java程序中的数据写到文件中。
OutputStream可以以字节为单位写数据。
OutputStream是所有字节输出流的顶层父类,他是抽象类,如果要用,需要使用子类,最常用的子类是FileOutputStream
FileOutputStream构造方法:

FileOutputStream(String name):参数要传递一个字符串类型的文件路径,表示向这个文件中写数据。
FileOutputStream(File file):参数要传递一个File类型的文件,表示向这个文件中写数据。

FileOutputStream其他方法:

void write(int b):向文件中写一个字节
void write(byte[] b):向文件中写一个字节数组
void write(byte[] b, int off, int len):向文件中写字节数组的一部分。参数off表示从哪个位置开始写,参数len表示写几个。
void close():关闭流(释放资源)

用字节输出流往文件中写输出的底层过程:
java程序=>JVM=>操作系统(OS)=>调用系统中写数据的方法==>把数据写入到文件中

一次写一个字节

字节输出流使用步骤:
  1. 创建字节输出流对象。
  2. 调用write方法写数据。
  3. 调用close方法使用资源

void write(int b):向文件中写一个字节
public static void main(String[] args) throws IOException {
    //注:比如参数列表中传递的是"D:\\text\\1.txt",文件的上级目录text不存在,将会报错
    FileOutputStream fos = new FileOutputStream("day13\\1.txt");
    fos.write(97);
    fos.write('中');//中文在内存中占据多个字节,只写一个字节无法正常往文件中写入汉字
    //如果采用的是GBK编码,汉字占2个字节
    //如果采用的是UTF-8的编码,汉字占3个字节
    //fos.write('a');
    //如果不关闭流,Java程序不结束的话,该文件会一直处于占用状态,无法删除.
    fos.close();
}
一次写一个字节数组

字节输出流使用步骤:
  1. 创建字节输出流对象。
  2. 调用write方法写数据。
  3. 调用close方法使用资源

void write(byte[] b):向文件中写一个字节数组
void write(byte[] b, int off, int len):向文件中写字节数组的一部分。参数off表示从哪个位置开始写,参数len表示写几个。
public static void main(String[] args) throws IOException {
    FileOutputStream fos = new FileOutputStream("day13\\2.txt");
    byte[] bytes = {97, 98, 99, 100, 101};
    fos.write(bytes);
    fos.write(bytes, 2, 3);
    fos.write("中国".getBytes());
    fos.write("100".getBytes());
    fos.close();
}
文件续写和换行

续写(追加写):使用两个参数的构造方法

FileOutputStream(File file, boolean append)
FileOutputStream(String name, boolean append)
参数:
	File file|String name:写入数据的目的地
	boolean append:续写的开关
                true:可以续写,使用构造方法创建对象,文件名相同,不会创建新的文件覆盖之前同名的文件,会继续往文件的末尾写数据
                false:不可以续写,使用构造方法创建对象,文件名相同,会创建一个新的空白文件覆盖之前同名的文件,在新的文件中写数据

换行:使用换行符号
  Windows系统里,每行结尾是 回车+换行 ,即 \r\n
  linux,Unix系统里,每行结尾只有 换行 ,即 \n
  Mac系统里,每行结尾是 回车 ,即 \r 。从 Mac OS X开始与Linux统一。

字节输入流

介绍

InputStream是字节输入流,用来读,可以将文件中的数据读取到Java程序中.
InputStream是字节输入流,所以会以字节为单位进行读取.
InputStream是所有字节输入流的顶层父类,是一个抽象类,如果要用,需要使用子类,最常用的子类是FileInputStream.
FileInputStream构造方法:

FileInputStream(String name):根据字符串的文件路径创建字节输入流对象。以后通过这个字节输入流都是从该文件中读取数据。
FileInputStream(File file):根据File对象创建一个字节输入流对象。

FileInputStream其他方法:

int read():从文件中读取一个字节并返回。如果已经读取结束了,返回-1
int read(byte[] b):从文件中读取数据放到字节数组中,返回读取到的字节个数,如果已经读取结束了,返回-1.
void close():释放资源,关闭流。
一次读一个字节

字节输入流的使用步骤:
  1. 创建字节输入流对象,绑定数据源文件。
  2. 调用read方法,从文件中读取数据。
  3. 调用close方法,释放资源。
中文在文件中是占用多个字节的,我们不能使用一次读取一个字节的方式读取中文。

int read():从文件中读取一个字节并返回。如果已经读取结束了,返回-1
public static void main(String[] args) throws IOException {
    //1.创建FileInputStream对象,构造方法中绑定要读取的数据源
    //没有该文件,会报错!
    FileInputStream fis = new FileInputStream("day13\\a.txt");
    int len;
    while((len = fis.read())!= -1){
        System.out.println((char)len);
    }
    fis.close();
}
一次读多个字节
int read(byte[] b):从文件中读取数据放到字节数组中,返回读取到的字节个数,如果已经读取结束了,返回-1.
public static void main(String[] args) throws IOException {
    FileInputStream fis = new FileInputStream("day13\\b.txt");
    byte[] bArr = new byte[3];
    int len;
    while((len = fis.read(bArr)) != -1){
        System.out.println(new String(bArr, 0, len));
    }
    fis.close();
}

文件复制

文件复制本质就是读和写,从源文件中读取字节,然后写到目标文件。
步骤:
  1. 创建字节输入流,用来读取。
  2. 创建字节输出流,用来写。
  3. 使用循环读取,将数据读取到字节数组中,然后将读取到的数据写到目的地文件。
  4. 释放资源(先关写的,在关读的)

private static void copyFile(FileInputStream fis, FileOutputStream fos) throws IOException {
    byte[] byteArr = new byte[1024];
    int len;
    while ((len = fis.read(byteArr))!= -1){
        fos.write(byteArr, 0, len);
    }
    fos.close();
    fis.close();
}

字符流

字符输入流

介绍

Reader是字符输入流,用来读取,可以将文件中的数据读取到Java程序中.
Reader是字符输入流,会以字符为单位进行读取.
Reader是所有字符输入流的顶层父类,是一个抽象类,如果要用需要使用子类,常用的子类FileReader.
FileReader构造方法:

FileReader(String fileName):参数是字符串类型的文件路径,表示向该文件中写数据。
FileReader(File file):参数是File类型的文件,表示向该文件中写数据。

FileReader其他方法:

int read():读取一个字符并返回,如果已经读取结束了,返回-1
int read(char[] cbuf):将数据读取到字符数组中,并返回读取到的字符个数,如果已经读取结束了,返回-1.
一次读一个字符

字符输入流的使用步骤:
  1. 创建字符输入流。
  2. 调用read方法读取。
  3. 释放资源

int read():读取一个字符并返回,如果已经读取结束了,返回-1
public static void main(String[] args) throws IOException {
    FileReader fr = new FileReader("day13\\b.txt");
    int len;
    while ((len = fr.read()) != -1) {
        System.out.print((char)len);
    }
    fr.close();
}
字符输入流读取一个字符数组

步骤:
  1. 创建字符输入流。
  2. 调用read方法读取。
  3. 释放资源

int read(char[] cbuf):将数据读取到字符数组中,并返回读取到的字符个数,如果已经读取结束了,返回-1.
public static void main(String[] args) throws IOException {
    FileReader fr = new FileReader("day13\\b.txt");
    char[] charArr = new char[1024];
    int len;
    while((len = fr.read(charArr)) != -1){
        System.out.println(new String(charArr, 0, len));
    }
}

字符输出流

介绍

Writer是字符输出流,用来写,可以将Java程序中的数据写到文件中。
Writer是字符流,会以字符为单位写数据。
Writer是所有字符输出流的顶层父类,是一个抽象类,如果要用,需要使用子类,常用的子类FileWriter
FileWriter构造方法:

FileWriter(String fileName):参数要传递字符串类型的文件路径,表示向该文件中写数据。
FileWriter(File file):参数要传递File类型的文件,表示向该文件中写数据。

FileWriter其他方法:

void write(String str):向文件中写一个字符串
void flush():刷新,将内存缓冲区中的数据刷新的文件中。
void close():关闭流

只有字符输出流必须要刷新
flush方法和close方法的区别
flush方法:刷新。 流在刷新之后还可以使用。
close方法:先刷新,然后关流。 流在关闭之后就不能使用了

写数据的五个方法

字符输出流写数据的五个方法:

void write(String str):向文件中写字符串
        void write(String str, int off, int len) :向文件中写字符串的一部分。从off位置开始写,写len个。
        void write(int c):向文件中写一个字符
        void write(char[] cbuf): 向文件中写字符数组
        void write(char[] cbuf, int off, int len):向文件中写字符数组的一部分。 参数off表示从哪个位置写,参数len表示写几个。
public static void main(String[] args) throws IOException {
    FileWriter fw = new FileWriter("day13\\e.txt");
    //public void write(int c) :写出一个字符。
    fw.write(97);
    //public void write(char[] cbuf) : 写字符数组中的多个字符
    char[] charArr = {'a', 'b', 'c', 'd'};
    fw.write(charArr);
    //public abstract void write(char[] b, int off, int len) : 写字符数组的一部分字符;off数组的开始索引,len写的字符个数
    fw.write(charArr, 0, 3);
    fw.write("hello");
    fw.write("helloworld", 0, 5);
    fw.flush();
    fw.close();

IO流的异常处理

JDK7之前

public static void main(String[] args) {
    FileWriter fw = null;
    try {
        fw = new FileWriter("day14\\1.txt");
        fw.write("你好");
        //fw.close();//如果出现异常,将跳过关流操作.
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            //如果fw不是null,才表示流成功创建了
            if(fw != null){
                fw.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

JDK7之后

在JDK7的时候,多了一种try…with…resourse语句,可以快捷地处理IO流中的异常以及释放资源的问题.
格式:

try(
    //定义流对象
    AAA aaa = new AAA();
    BBB bbb = new BBB();
){
    可能产生异常的代码
    aaa.read();
    bbb.write();
}catch(定义一个异常相关的变量,接收异常对象){
    异常的处理逻辑
}

注意:
  1.在try的后边增加一个(),在()中定义流对象.那么这些流对象的作用域,就只在try中有效,执行完try中的代码,会自动帮助我们释放流对象,省略finally
  2.注意try后边的小括号中,不是任意对象都可以放,只有实现了AutoCloseable接口的对象才能放.

public static void main(String[] args) {
    try (FileWriter fw = new FileWriter("day14\\2.txt");){
        fw.write("HelloWorld");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

properties

properties的基本使用

Properties是双列集合,叫做属性集。
特点:
  1. Properties实现Map接口,拥有Map接口中的所有的方法。
  2. Properties没有泛型,里面的键和值都是字符串。
  3. Properties支持和流一起操作,可以从流中加载键值对【从文件中读取键值对】
构造方法:

Properties():创建的是不包含任何元素的Properties集合。

其他方法:

Object setProperty(String key, String value):添加键值对元素。
(记住)String getProperty(String key):根据键获取值。
Set<String> stringPropertyNames():获取Properties中所有的键并放入到Set集合中返回。

properties从文件读取键值对

Properties有关流的方法,可以从文件中读取键值对.
Properties集合中的方法load(重点)
我们可以使用Properties集合中的方法load,把硬盘文件中保存的键值对,读取到内存中集合里边使用(硬盘–>内存)

void load(InputStream inStream) 传递字节输入流,不能读取含有中文的文件,可以传递InputStream的任意子类对象
void load(Reader reader)  传递字符输入流,可以读取含有中文的文件,可以传递Reader的任意子类对象

使用步骤;
  1.创建Properties集合对象
  2.使用Properties集合中的方法load,把硬盘文件中保存的键值对,读取到内存中集合里边使用
  3.遍历Properties集合
注意:
  1.在Properties集合的配置文件中,可以使用#进行注释,被注释的键值对不会被读取
  2.在Properties集合的配置文件中,健和值之间可以使用=(最规范),空格,冒号等一些符号作为键与值的分割符号,每一个键值对要换行.
  3.在Properties集合的配置文件中,健和值默认都是String类型,不需要添加引号,否则会画蛇添足
  4.配置文件一般以.properties结尾(软性规定)

写键值对到文件中

Properties集合中的方法store(了解-扩展)
我们可以使用Properties集合中的方法store,把集合中的临时数据,持久化到硬盘中存储(内存–>硬盘)

 void store(OutputStream out, String comments)
 void store(Writer writer, String comments)
 方法的参数:
     OutputStream out:传递字节输出流,不能写中文,会出现乱码,可以传递OutputStream的任意子类对象
     Writer writer:传递字符输出流,能写中文,不会出现乱码,可以传递Writer的任意的子类对象
     String comments:注释解释说明我们保存文件是做什么用的,一般传递""
         注释不能写中文,默认使用Unicode编码,写中文会出现乱码

使用步骤:
  1.创建Properties集合对象,往集合中添加数据
  2.使用Properties集合中的方法store,把集合中的临时数据,持久化到硬盘中存储

ResourceBundle

java.util.ResourceBundle:操作资源的工具类
作用:
  我们可以使用ResourceBundle类中的方法读取以.properties结尾的文件
注意:
  1.ResourceBundle是一个抽象类,我们无法直接创建对象使用,
    我们可以使用ResourceBundle类中的静态方法获取ResourceBundle的子类对象

    static ResourceBundle getBundle(String baseName)
    参数:
        String baseName:传递以.properties结尾的文件名称
        prop.properties==>传递prop
        data.properties==>传递data

2.ResourseBundle读取的properties结尾的文件必须放在当前模块的src下边,否则获取对象找不到配置文件,会抛出异常

MissingResourceException: Can't find bundle for base name data, locale zh_CN

ResourceBundle类的getString方法:用于读取配置文件(存储的都是键值对)

    String getString(String key)  根据配置文件中key,读取配置文件中的value

注意:配置文件中的key和value不要使用中文

缓冲流

缓冲流
 字节缓冲流
  字节输入缓冲流:BufferedInputStream
  字节输出缓冲流:BufferedOutputStream
 字符缓冲流
  字符输入缓冲流:BufferedReader
  字符输出缓冲流:BufferedWriter
缓冲流的特点是效率高,缓冲流内部有一个缓冲区,可以提高效率[缓冲区使用的是数组]
缓冲流本身并不具备读或写的功能,它的作用是给其他流提供加速.

字节缓冲流

字节缓冲输入流

java.io.BufferedInputStream:字节缓冲输入流 extends InputStream字节输出流
继承自父类共性的成员方法:

     int read() 一次读取一个字节并返回
     int read(byte[] b) 使用数组缓冲,一次读取多个字节
     void close() 关闭此输入流并释放与该流关联的所有系统资源。

构造方法:

     BufferedInputStream(InputStream in) 创建一个具有默认缓冲区大小的BufferedInputStream对象
     BufferedInputStream(InputStream in, int size) 创建具有指定缓冲区大小的 BufferedInputStream对象
         参数:
         InputStream in:传递字节输入流,可以传递InputStream的任意子类对象
             我们可以传递FileInputStream对象,缓冲流就会给FileInputStream对象增加一个缓冲区(字节数组)
             提高FileInputStream读取文件的效率
         int size:指定缓冲区的大小(数组的长度),不写使用默认值
         private static int DEFAULT_BUFFER_SIZE = 8192;

使用步骤(重点):
  1.创建BufferedInputStream对象,构造方法中传递FileInputStream对象
  2.使用BufferedInputStream对象中的方法read,以字节的方式读取文件
  3.释放资源

字节缓冲输出流

java.io.BufferedOutputStream:字节缓冲输出流 extends OutputStream字节输出流
继承自父类的共性成员方法:

    public void close() :关闭此输出流并释放与此流相关联的任何系统资源。
    public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。
    public void write(byte[] b) :将 b.length字节从指定的字节数组写入此输出流。
    public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。
    public abstract void write(int b) :将指定的字节输出流。

构造方法:

    BufferedOutputStream(OutputStream out) 创建一个新的缓冲输出流,具有默认缓冲区大小
    BufferedOutputStream(OutputStream out, int size) 创建一个新的缓冲输出流,具有指定缓冲区大小
    参数:
        OutputStream out:传递字节输出流,可以传递OutputStream的任意子类对象
        我们可以传递FileOutputStream对象,缓冲流就会给FileOutputStream对象增加一个缓冲区(字节数组),提高FileOutputStream读取文件的效率     
        int size:指定缓冲区的大小(数组的长度),不写使用默认值

使用步骤(重点):
  1.创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象
  2.使用BufferedOutputStream对象中的方法write,把数据写入到内存缓冲区中
  3.使用BufferedOutputStream对象中的方法flush,把内存缓冲区中数据刷新到文件
  4.释放资源(会先调用flush方法刷新数据到文件)

字符缓冲流

字符缓冲输入流

java.io.BufferedReader:字符缓冲输入流 extends Reader字符输入流
继承自父类的共性成员方法:

    int read() 读取单个字符。
    int read(char[] cbuf) 将字符读入数组。
    void close() 关闭该流并释放与之关联的所有资源。

构造方法:

    BufferedReader(Reader in) 创建一个使用默认大小输入缓冲区的缓冲字符输入流。
    BufferedReader(Reader in, int sz) 创建一个使用指定大小输入缓冲区的缓冲字符输入流。
    参数:
       Reader in:传递字符输入流,可以传递Reader的任意的子类对象
                 我们可以FileReader,缓冲流就会给FileReader增加一个缓冲区
                 提高FileReader读取文件的效率
       int sz:指定缓冲区的大小(数组长度),不指定使用默认值

特有的成员方法:

String readLine() 读取一个文本行。一次可以读取一行数据
	通过下列字符之一即可认为某行已终止:换行 ('\n')、回车 ('\r') 或回车后直接跟着换行(\r\n)。
返回:
        包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null

使用步骤(重点:)
  1.创建BufferedReader对象,构造方法中传递FileReader对象
  2.使用BufferedReader对象中的方法read|readLine,以字符的方式读取文件
  3.释放资源

字符缓冲输出流

java.io.BufferedWriter:字符缓冲输出流 extends Writer:字符输出流
继承自父类共性的成员方法:

 public abstract void close() :关闭此输出流并释放与此流相关联的任何系统资源。
 public abstract void flush() :刷新此输出流并强制任何缓冲的输出字符被写出。
 public void write(int c) :写出一个字符。
 public void write(char[] cbuf) :将 b.length字符从指定的字符数组写出此输出流。
 public abstract void write(char[] b, int off, int len) :从指定的字符数组写出 len字符,从偏移量 off开始输出到此输出流。
 public void write(String str) :写出一个字符串
 public void write(String str, int off, int len) 写入字符串的某一部分。

构造方法:

 BufferedWriter(Writer out) 创建一个使用默认大小输出缓冲区的缓冲字符输出流。
 BufferedWriter(Writer out, int sz)  创建一个使用给定大小输出缓冲区的新缓冲字符输出流。
 参数:
     Writer out:传递字符输出流,可以传递Writer的任意的子类对象
         我们可以FileWriter,缓冲流就会给FileWriter增加一个缓冲区
         提高FileWriter写入文件的效率
    int sz:指定缓冲区的大小(数组长度),不指定使用默认值

特有的成员方法(重点):

 void newLine() 写入一个行分隔符。写一个换行符号,根据系统不同,而写不同的换行符号
     Windows系统里,每行结尾是 回车+换行 ,即 \r\n
     linux,Unix系统里,每行结尾只有 换行 ,即 \n
     Mac系统里,每行结尾是 回车 ,即 \r 。从 Mac OS X开始与Linux统一。

使用步骤(重点):
  1.创建BufferedWriter对象,构造方法中传递FileWriter对象
  2.使用BufferedWriter对象中的方法write,把数据写入到内存缓冲区中
  3.使用BufferedWriter对象中的方法flush,把内存缓冲区中的数据刷新到文件中
  4.释放资源(会先调用flush方法刷新数据)

转换流

使用FileReader读取GBK编码的文件:会出现乱码,这是编码和解码不一致导致
GBK:采用的双字节编码,一个中文占用2个字节
UTF-8:采用多字节编码,一个中文占用3个字节

编码表

就是生活中的文字和计算机中文字的对应关系表
a–>97–>01100001=>存储到计算机中
中–>20013–>‭0010000000001011‬=>存储到计算机中
编码:把能看懂的文字,转换为看不懂的文字(字符=>字节)
解码:把看不懂的文字,转换为能看懂的文字(字节==>字符)
常用的编码表:
ASCII字符集 :英文,数字,标点符号和计算机中文字的对应关系
0–>48 A–>65 a–>97
ISO-8859-1字符集:拉丁码表
拉丁码表,别名Latin-1,用于显示欧洲使用的语言,包括荷兰、丹麦、德语、意大利语、西班牙语等。
ISO-8859-1使用单字节编码,兼容ASCII编码。不支持中文
GBxxx字符集:国标
GB就是国标的意思,是为了显示中文而设计的一套字符集。兼容ASCII表
GB2312:简体中文码表。 7000多个简体汉字
GBK:目前操作系统默认中文码表(简体,繁体),存储一个中文使用2个字节,21003个汉字
GB18030:最新的中文码表。包含的文字最全(简体,繁体,少数民族,日韩文字)
Unicode字符集 :万国码UTF-8:最常用的万国表,兼容所有国家的文字
编码规则:
128个US-ASCII字符,只需一个字节编码。
拉丁文等字符,需要二个字节编码。
大部分常用字(含中文),使用三个字节编码。
其他极少使用的Unicode辅助字符,使用四字节编码。

字符转换输入流

java.io.InputStreamReader:字符转换输入流 extends Reader:字符输出流
作用:
InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。解码:字节==>字符
继承自父类的共性成员方法:

        int read() 读取单个字符。
        int read(char[] cbuf) 将字符读入数组。
        void close() 关闭该流并释放与之关联的所有资源。

构造方法:

InputStreamReader(InputStream in)创建一个使用默认字符集的 InputStreamReader。
InputStreamReader(InputStream in, String charsetName) 创建使用指定字符集的 InputStreamReader。
参数:
	InputStream in:传递字节输入流,可以传递InputStream的任意的子类对象(读取文件中的字节)
	String charsetName:传递编码表名称,不区分大小写的可以传递GBK(gbk),UTF-8(utf-8)...,不写默认使用IDEA设置的编码(UTF-8)

使用步骤(重点):
  1.创建InputStreamReader对象,构造方法中传递FileInputStream对象和指定的编码表名称
  2.使用InputStreamReader对象中的方法read读取文件
  3.释放资源
注意:
  InputStreamReader构造方法中指定的编码表名称必须和文件的编码一致,否则会出现乱码

字符转换输出流

java.io.OutputStreamWriter:字符转换输出流 extends Writer:字符输出流
作用:
OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。编码:字符==>字节
继承自父类共性的成员方法:

        public abstract void close() :关闭此输出流并释放与此流相关联的任何系统资源。
        public abstract void flush() :刷新此输出流并强制任何缓冲的输出字符被写出。
        public void write(int c) :写出一个字符。
        public void write(char[] cbuf) :将 b.length字符从指定的字符数组写出此输出流。
        public abstract void write(char[] b, int off, int len) :从指定的字符数组写出 len字符,从偏移量 off开始输出到此输出流。
        public void write(String str) :写出一个字符串
        public void write(String str, int off, int len) 写入字符串的某一部分。

构造方法:

        OutputStreamWriter(OutputStream out)创建使用默认字符编码的 OutputStreamWriter。
        OutputStreamWriter(OutputStream out, String charsetName) 创建使用指定字符集的 OutputStreamWriter。
        参数:
            OutputStream out:传递字节输出流,可以传递OutputStream的任意子类对象(把字符转换之后的字节写入到文件中)
            String charsetName:传递编码表名称,不区分大小写的可以传递GBK(gbk),UTF-8(utf-8)...,不写默认使用IDEA设置的编码(UTF-8)

使用步骤(重点):
  1.创建OutputStreamWriter对象,构造方法中传递FileOutputStream对象和指定的编码名称
  2.使用OutputStreamWriter对象中的方法write,把数据写入到内存缓冲区中(字符==>字节)
  3.使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的数据,刷新到文件中(使用字节输出流把字节写入到文件)
  4.释放资源(会先调用flush方法刷新数据)

序列化流

对象的序列化流

java.io.ObjectOutputStream:对象的序列化流 extends OutputStream:字节输出流
作用:把对象以流的方式写入到文件中保存
构造方法:

        ObjectOutputStream(OutputStream out) 创建写入指定 OutputStream 的 ObjectOutputStream。
        参数:
            OutputStream out:传递字节输出流,可以传递OutputStream的任意子类对象
    特有的成员方法:
        void writeObject(Object obj) 将指定的对象写入 ObjectOutputStream。

使用步骤:
  1.创建ObjectOutputStream对象,构造方法中传递FileOutputStream对象
  2.使用ObjectOutputStream对象中的方法writeObejct,把对象写入到文件中
  3.释放资源

在进行序列化|反序列化的时候,会抛出NotSerializableException:没有序列化异常
类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。
Serializable接口是一个标记型接口,类实现了Serializable接口,接口就会给类添加上一个标记
当我们进行序列化和反序列化的时候,会检查类上是否有标记,有则序列化反序列化成功,没有会抛出异常
去市场买肉=>肉上会有一个检查合格的章=>放心购买=>买回来肉怎么吃=>随意:炖,炒,刷…
类=>添加上了标记=>放心进行序列化和反序列化了=>类做不做其他的用途没有影响

对象的反序列化流

java.io.ObjectInputStream:对象的反序列化流 extends InputStream:字节输入流
作用:把文件中保存的对象以流的方式读取出来使用
构造方法:

        ObjectInputStream(InputStream in) 创建从指定 InputStream 读取的 ObjectInputStream。
        参数:
        InputStream in:传递字节输入流,我们可以传递InputStream的任意子类对象特有的成员方法:
        Object readObject() 从 ObjectInputStream 读取对象。 

使用步骤:
  1.创建ObjectInputStream对象,构造方法中传递FileInputStream对象
  2.使用ObjectInputStream对象中的方法readObject,读取文件中保存的对象
  3.释放资源

    public final Object readObject() throws IOException, ClassNotFoundException
    readObject方法声明抛出了两个异常对象
    ClassNotFoundException:找不到class文件异常

反序列化有两个前提:1.类实现Serializable接口 2.类有对应的class文件(Person.class)

static&&transient

transient:瞬态关键字
 被transient关键字修饰的变量不能被序列化
static:静态关键字
 被static修饰的成员属于类,不属于某一个对象,被所有的对象所共享使用
 被static修饰的成员,也不能序列化,序列化的是对象

序列号冲突异常

Serializable接口规定
  可序列化类可以通过声明名为 “serialVersionUID” 的字段(该字段必须是静态 (static)、最终 (final) 的 long 型字段)
  显式声明其自己的 serialVersionUID:

        static final long serialVersionUID = xxL;

  在类中手动添加了一个序列号,无论类是否修改,序列号都是固定写死的常量值,值是不会改变的,也就不会抛出异常了

打印流

java.io.PrintStream:字节打印流 extends OutputStream:字节输出流
特点:
  1.PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
    PrintStream流中有两个特有的方法:print,println
  2.与其他输出流不同,PrintStream 永远不会抛出 IOException,创建对象的时候,传递路径不存在,可能会抛出文件找不到异常
  3.PrintStream叫打印流,只负责输出(打印),不能读取
  构造方法:

        PrintStream(File file)  打印流的目的地是一个文件
        PrintStream(OutputStream out) 打印流的目的地是一个字节输出流
        PrintStream(String fileName) 打印流的目的地是一个文件路径

成员方法:
  1.继承自父类OutputStream的共性的成员方法

	write:使用write写数据,查看的时候,会查询编码表
        public void close() :关闭此输出流并释放与此流相关联的任何系统资源。
        public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。
        public void write(byte[] b) :将 b.length字节从指定的字节数组写入此输出流。
        public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。
        public abstract void write(int b) :将指定的字节输出流。

  2.自己特有的成员方法:print,println写数据,原样输出

            void print(Object x)    可以写任意类型数据,不换行
            void println(Object x)  可以写任意类型的数据,换行

使用步骤(重点):
  1.创建PrintStream对象,构造方法中绑定要输出的目的地
  2.使用PrintStream对象中的方法write,print,println,把数据写入到文件中
  3.释放资源

装饰者模式

装饰模式可以在不改变原类的基础上对类中的方法进行扩展增强,实现原则为:
  1.装饰类和被装饰类必须实现相同的接口,继承相同的父类
  2.在装饰类中必须传入被装饰类的引用(对象),使用构造方法传递
  3.在装饰类中对需要扩展的方法进行扩展
  4.在装饰类中对不需要扩展的方法调用被装饰类中的同名方法

commons-io

commons-io是apache开源基金组织提供的一组有关IO操作的类库,可以挺提高IO功能开发的效率。
导入jar包的步骤:
1. 新建一个文件夹叫做lib
2. 将jar包复制到lib文件夹下
3. 点lib文件夹右键选择 Add as Library

org.apache.commons.io.IOUtils: 操作IO流的工具类

        1. public static int copy(InputStream in, OutputStream out);
            把input输入流中的内容拷贝到output输出流中,返回拷贝的字节个数(适合文件大小为2GB以下)
        2. public static long copyLarge(InputStream in, OutputStream out);
            把input输入流中的内容拷贝到output输出流中,返回拷贝的字节个数(适合文件大小为2GB以上)

org.apache.commons.io.FileUtils:操作文件的工具类

        static String readFileToString(File file) 读取一个文件以字符串形式返回
        static void writeStringToFile(File file, String data) 把字符串写入到一个文件中
        static void copyFile(File srcFile, File destFile) 文件复制
        static void copyFileToDirectory(File srcFile, File destDir) 把一个文件复制到一个文件夹中
        static void copyDirectoryToDirectory(File srcDir, File destDir) 文件夹复制
    注意:
        以上4个方法的参数都是File对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值