黑马程序员——java基础(IO部分知识梳理)上

来源:互联网 发布:linux tomcat 慢 编辑:程序博客网 时间:2024/05/29 04:16
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------

一、IO流总述

1.流是一种特殊的“容器”

    IO流是Java基础部分笔墨较重的一个知识板块,从其功能上看,它们似乎可以归类为“容器”。当然,它们同常规容器(如集合/数组)还是有很大不同的。其一,我们之前遇到的常规容器仅仅是“保存”数据,而各种流对象的作用更多的是用来“搬运”数据(但是搬运的过程也同时发挥保存的作用);其二,常规容器是内存中的内部通信,而流(在只考虑本地应用的情况下)更多的是用来实现内存与永久存储设备(比如硬盘)之间的通信;其三,流可以作为网络中数据传输的容器。

2.流是个很重要的东东

    IO流在Java基础知识中属于需要重点掌握的内容。流重点的原因在于它丰富的功能,这些功能似乎可以概括成一句话:流是用来通信的。

    本地内存与控制台之间的通信需要流;本地内存与本地永久存储设备的通信需要流;本地与网络之间的通信需要流;就连线程之间的通信也需要流……

    流再使用的过程中不断的丰富与完善,现在,流已经成为了一个分工明确、格式统一、便于使用的完整的体系。

3.此篇博客的写作目的

    这部分博客旨在总结流对象和常用流的方法。


二、常见流对象

类 FileWriter 

0.这是一个字符Writer流子类
  1.应用形式
    import java.io.FileWriter;//导入对应的子类
    import java.io.IOException;
    方法()throws 可能导致的异常//异常处理方式之一
    FileWriter 流(对象)名 = new FileWriter("目标文件.必须指定文件后缀");//建立对象+传入参数
    对象名.方法名();
  2.对象创建细节
    创建出的对象就是 流
    创建对象时必须提供充足的文件信息,否则可能抛出 IOException 异常
    创建对象时会新建一个文件
    若文件不存在,则对象根据提供的信息自动创建//新建
    若文件存在,则覆盖(覆盖是指:清空原文件中所有内容,写入对象指定数据)//相当于新建
  3.方法
    1)write 写入流
      对象名.write("欲输入内容");
      将数据写入到临时数据缓冲区中(写入流中),但不是预期目标(目标文件)
      写入动作失败时会抛出 IOException 异常
    2)flush 刷新流
      对象名.flush();
     刷新流(临时数据缓冲区),实现将流中的数据写入预期目标
    3)close 关闭流
      对象名.close();
      关闭流,关闭之前必须刷新流(此刷新过程为自动完成的)
      关闭流后,无法对其进行write/flush操作,否则抛出 IOException 异常
      关闭已关闭的流无效

类 FileReader

    0.这是一个字符Writer流子类
    1.应用形式
        import java.io.FileReader;//导入对应的子类
        import java.io.IOException;
        方法() throws 可能导致的异常//异常处理方式之一
        FileReader 流(对象)名 = new FileReader("目标文件.必须指定文件后缀");//建立对象+传入参数 
        对象名.方法名();
    2.对象创建细节
        创建出的对象就是 流 ,流关联了(目标文件)预期目标(相当于将文件的内容载入了流,文件末尾就是流末尾)
        创建对象时必须提供充足的文件信息,否则可能抛出 IOException 异常(此流不可指向不存在的文件)
    3.方法
        1)read() 读取单个字符
            对象名.read();
            从预期目标中读取一个字符,返回该字符的 int 值
            若已经读取到了流的末尾,返回 -1 (正常值得范围为 0x0000~0xFFFF 0~62235)
            读取已经读取过末尾(返回过 -1)的流,依然返回 -1
        2)read(char[] cbuf);
            对象名.read(char[] cbuf);
            从预期目标中依次读取字符,将返回的结果(结果的类型为 char)顺次存入数组(数组必须已经存在)
            若读取操作时,将已存在的数组存满,则读取停止;再次调用此方法,会从上次停止读取的位置继续,将字符从头开始顺次存入数组
            每次调用此方法将结果存入数组时,不会清空数组中原有内容
            此方法具有返回值,返回值类型为 int ,值的大小是读取到的字符的个数
            若已经读取到了流的末尾,返回 -1 (正常值得范围为 0x0000~0xFFFF 0~62235)
            读取已经读取过末尾(返回过 -1)的流,依然返回 -1

类 BufferedWriter

    0.这是一个字符Writer缓冲区子类
    1.应用形式
        import java.io.BufferedWriter;//导入对应的子类
        import java.io.FileReader;
        import java.io.IOException;
        方法()throws 可能导致的异常//异常处理方式之一
        FileWriter 流(对象)名 = new FileWriter("目标文件.必须指定文件后缀");//建立对象+传入参数
        BufferedWriter 缓冲区名 = new BufferedWriter(流名);//建立对象+传入参数 
    2.对象创建细节
        创建出的对象就是 缓存区 ,创建缓存区对象时需要将一个指向预定目标的流对象作为参数传入
        //必须指定缓存区要为哪个流进行缓存服务,流则指定了预定目标
    3.方法
        1)write 写入缓冲区
            缓冲区名.write("欲输入内容");
            将数据写入到临时数据缓冲区中,但不是预期目标(目标文件)
            写入动作失败时会抛出 IOException 异常
        2)flush 刷新缓冲区
            缓冲区名.flush();
            刷新缓存区,实现将流中的数据写入预期目标
        3)close 关闭缓冲区
            缓冲区名.close();
            关闭缓冲区,关闭之前必须刷新缓存区(此刷新过程为自动完成的)
            关闭缓冲区后,无法对其进行write/flush操作,否则抛出 IOException 异常
            关闭已关闭的缓冲区无效
            缓冲区关闭的同时,缓冲区所服务的流也会关闭

类 BufferedReader

    0.这是一个字符Writer缓冲区子类
    1.应用形式
        import java.io.BufferedReader;
        import java.io.FileNotFoundException;
        import java.io.FileReader;
        import java.io.IOException;
        方法()throws 可能导致的异常//异常处理方式之一
        FileReader 流(对象)名 = new FileReader("目标文件.必须指定文件后缀");
        BufferedReader 缓冲区名 = new BufferedReader(流名);//建立对象+传入参数
    2.对象创建细节
        创建出的对象就是 缓存区 ,创建缓存区对象时需要将一个指向预定目标的流对象作为参数传入
        //必须指定缓存区要为哪个流进行缓存服务,流则指定了预定目标
    3.方法
        1)readLine() 行读取
            缓冲区名.readLine();
            将文件中的一行通过流读取进缓冲区//在遇到换行符之前,都叫一行
            此方法具有返回值,其类型为 String ,其值为读取到的内容
            若读取到文件末尾则会停止读取并返回最后读取的内容
            若读取到文件末尾后继续读取则会返回 null

类 FileOutputStream

    0.这是一个字节输出流子类
    1.应用形式
        import java.io.BufferedOutputStream;
        import java.io.FileOutputStream;
        import java.io.IOException;
        方法()throws 可能导致的异常//异常处理方式之一
        FileOutputStream 流(对象)名 = new FileOutputStream("目标文件.必须指定文件后缀");
    2.对象创建细节
        创建出的对象就是 流 ,创建缓存区对象时需要将预定目标作为参数传入
    3.方法
        1)write 写入流
            流名.write("欲输入内容");
            write(int);//只对0-255的int值有效(实际上是将int截取了低8位)
            将数据写入预期目标(目标文件)
            写入动作失败时会抛出 IOException 异常
        2)close 关闭流
            流名.close();
            关闭流,关闭之前不用刷新流因为其flush()为空函数体(注意不是无结构体)
            关闭流后,无法对其进行write/flush操作,否则抛出 IOException 异常
            关闭已关闭的流无效

类 FileInputStream

    0.这是一个字节输出流子类
    1.应用形式
        import java.io.BufferedInputStream;
        import java.io.FileInputStream;
        import java.io.IOException;
        方法()throws 可能导致的异常//异常处理方式之一
        FileInputStream 流(对象)名 = new FileInputStream("目标文件.必须指定文件后缀");
    2.对象创建细节
        创建出的对象就是 流 ,创建缓存区对象时需要将预定目标作为参数传入
    3.方法
        1)read 读入流
            流名.read();
            将数据读出预期目标(目标文件),读取一个字符需要两次动作
            写入动作失败时会抛出 IOException 异常

        2)close();
            流名.close();关闭流,关闭之前不用刷新流因为其flush()为空函数体(注意不是无结构体)
            关闭流后,无法对其进行write/flush操作,否则抛出 IOException 异常
            关闭已关闭的流无法二次关闭

类 BufferedInputStream

    0.这是一个字节Input缓冲区子类
    1.应用形式
        import java.io.BufferedInputStream;
        import java.io.FileInputStream;
        import java.io.IOException;
        方法()throws 可能导致的异常//异常处理方式之一
        FileInputStream 流名 = new FileInputStream(预定目标);
        BufferedInputStream 缓冲区名 = new BufferedInputStream(流名);//建立对象+传入参数
    2.对象创建细节
        创建出的对象就是 缓存区 ,创建缓存区对象时需要将一个指向预定目标的流对象作为参数传入
        //必须指定缓存区要为哪个流进行缓存服务,流则指定了预定目标
    3.方法
        1)read() 读取
            缓冲区名.read();
            将文件中的字节通过流读取进缓冲区//在遇到换行符之前,都叫一行
            若读取到文件末尾则会返回-1
            若读取到文件末尾后继续读取则会返回 null

类 FileOutputStream

    0.这是一个字节输出流子类
    1.应用形式
        import java.io.BufferedOutputStream;
        import java.io.FileOutputStream;
        import java.io.IOException;
        方法()throws 可能导致的异常//异常处理方式之一
        FileOutputStream 流(对象)名 = new FileOutputStream("目标文件.必须指定文件后缀");
    2.对象创建细节
        创建出的对象就是 流 ,创建缓存区对象时需要将预定目标作为参数传入
    3.方法
        创建出的对象就是 缓存区 ,创建缓存区对象时需要将一个指向预定目标的流对象作为参数传入
        //必须指定缓存区要为哪个流进行缓存服务,流则指定了预定目标
    3.方法
        1)write() 写入
            缓冲区名.write();
            将缓冲区中内容逐字节的写入目标//在遇到换行符之前,都叫一行

序列流

(多个流的有序排列)

序列流只负责源,从输入流集合的第一个流开始,读完后读第二个输入流,直到读完

将多个流进行了有序排列并合并成一个流


类 SequenceInputStream

    输入序列流,接收的数据类型为枚举,枚举中是复数个字节输入流对象,以提供给 SequenceInputStream 作为合并成序列的原件

    SequenceInputStream(枚举对象)


打印流

(保证数据原样性,但是不能保证数据大小)
类 PrintWriter
    0.字符打印流,提供多样的打印功能
        不会抛出异常
    1.声明
        PrintWriter 流名 = new PrintWriter(目标);
    2.方法
        1)write(int);
            将int型的数写入流,方法截取数据的低8位作为字节写入,忽略高24位
        2)print();
            将传入的数据写入流,方法会保持数据的表现形式(参数97,则目标中就是97,而不是a)//先变字符串在写入流
        3)若打印的方法为println/printf/format中的一种,通过传入额外的boolean型参数可以控制 PrintWriter 是否自动刷新


类 PrintStream

    0.提供多样的打印功能
       不会抛出异常
        不用手动flush();
    1.声明
        PrintStream 流名 = new PrintStream(目标);
    2.方法
        1)write(int);
            将int型的数写入流,方法截取数据的低8位作为字节写入,忽略高24位
        2)print();
            将传入的数据写入流,并自动flush,方法会保持数据的表现形式(参数97,则目标中就是97,而不是a)//先变字符串在写入流

类 ObjectOutputStream

    0.将对象排列成序列保存进可长期保存数据的地方
    1.被保存的对象所属的类必须实现 Serializable 接口
    2.必须规定要保存成什么文件
    3.必须将一个流实例加载进 ObjectOutputStream 对象,被加载的流中封装了"保存成什么文件"
    4.常用形式
        ObjectOutputStream 流名 = new ObjectOutputStream(new FileOutputStream("保存成什么文件(一般是*.object)"));
    5.常用操作
        流名.writeObject(对象名);//此语句将对象通过对象操作流调用的流对象把对象保存到指定的
    6.细节
        序列化后的文件包含默认的或者用户指定的ID号,用于反序列化时匹配*.class文件
        静态成员的值无法被序列化,因为静态的成员属性作为对象的成员可以保存于对象中,但是静态属性的值则保存在静态区,反序列化后静态值为0
类 ObjectInputStream
    0.对用 ObjectOutputStream 保存的对象进行反序列化,每使用一次则读取其中的一个对象
    1.被保存的对象所属的类必须实现 Serializable 接口
    2.必须指定已存在的对象序列保存文件
    3.必须将一个流实例加载进 ObjectInputStream 对象,被加载的流中封装了"保存成什么文件"
    4.常用形式
        ObjectInputStream 流名 = new ObjectInputStream(new FileInputStream("读取的对象文件(一般是*.object)"));
        //对象是通过类才构造出来的
        //读取目标文件中的数据并将之还原为对象的动作只有目标文件是不够的,还需要对象所对应的*.class文件,否则会出现ClassNotFoundException
        //所使用的类必须与构造对象时的类一模一样,否则抛出InvalidClassException
    5.常用操作
        流名.readObject(目标);//此语句将对象通过对象操作流调用的流对象把对象从目标读取出来 
        可以通过下面的形式读取到对象
        类名 对象名 = (类名) 流名.readObject(对象名);//将直接通过流读取的字节强制转换为原版的类对象

流转换

使用字符流操作字节

类 InputStreamReader

   0.此类将字节输入流转换成字符输入流,是一个转换流
    1.需要导入包
        import java.io.InputStreamReader;
    2.创建实例
        InputStreamReader 转换流名 = new InputStreamReader(欲转换的字节流名);

类 OutputStreamWriter

   0.此类将字符输出流转变成字节输出流
    1.需要导入包
        import java.io.OutputStreamWriter;
    2.创建实例
        OutputStreamWriter 转换流名 = new OutputStreamWriter(欲转换的字节流名);

        常用写法(通过加载缓冲区的字符流操作字节)
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(预定目标)));

通过指定的码表配合字节流进行字符的写出
    1.因为是用字节流输出,但是输出的内容为字符流,所以一定会用到转换流
    2.常用格式如下
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk_3.txt"),"GBK");
    3.细节
        用此格式声明一个实例,此实例指定了输出预定目标和所用的编码表
        此对象调用write方法工作时,通过转换流与指定的编码表将write传入的内容查"GBK"表储存,又通过"GBK"表转为所需的字符存入目标

类 RandomAccessFile

   0.随机访问文件类,自身具备读写功能,但是,用此类读写数据时要求数据具有规律(比如3个字节一组)
    1.此类的对象内部维护了一个 byte 指针,通过指针可以操作数组中的元素
        此数组可以自动延长
    2.可以通过getFilePointer方法获取指针的位置,和通过seek方法设置指针的位置。
    3.其实该对象就是将字节输入流和输出流进行了封装。 
    4.该对象的源或者目的只能是文件。通过构造函数就可以看出。 
    5.实例创建
        RandomAccessFile 对象名 = new RandomAccessFile("文件名", "打开方式");//打开方式只有4种
    6.方法
        1)close();//关流
        2)write("字符串".getBytes());
            //向指定的目标写入字节,重复以一个文件为目标的写入(关流、新建写入、关流、新...)不会重置文件,只会覆盖数据;此特性可以用来修改数据
        3)writeInt();//用四字节写入
        4)read(容器);//会从指定的文件中读取并装满容器
        4)readInt();//会从指定的文件中4个字节,两个字节存一个字,数字会在前面补零
        5)getFilePointer();//获取文件指针位置
        6)seek(m*n);//用来设置文件指针的位置,m指想取得第几组的位置,一般定义的每组的长度
            //可以实现多个线程分别从指定的地方同时写同一个文件

类 PipedInputStream 和 PipedOutputStream

    0.管道流的输入流与输出流之间可以关联
        所谓的关联:单线程-->读写链接(不建议)
        多线程-->读写同时(常规)
    1.管道流的关联
        1)管道流在声明的时候直接传入与关联的管道流对象
        2)管道流对象.connect(管道流对象);
            关联后的流对有关联性,输出流输出的数据会传至输入流输入;输入流输入的数据会传至输出流输出

流 DataInputStream 和 DataOutputStream

   0.用来操作基本数据类型的流对//不同于ObjectStream,那是序列化对象的
    1.声明这些类的实例需要将一个基本流作为参数传入
        new Data(Out/In)putStream(基本流对象)
    2.方法
        1)writeUTF(String)与机器无关方式用UTF-8码表将字符写入基本输出流
            通过此方法传入的数据带有标记(黑色小方块)
            通过此方法传入的数据必须使用与之相对应的流的方法才能读取
        2)readUTF()
            是与上面方法对应的方法

流 ByteArrayInputStream 和 ByteArrayOutputStream

(只操作内存,源和目的都是内存)
    0.ByteArrayOutputStream 流的对象包含一个可自动延长的数组,可通过toByteArray()和toString()获取数据,
        ByteArrayInputStream 内部包含一个内部缓冲区,以及可以跟踪read方法的内部计数器
    1.这两个流的对象无法关闭(关闭无效),因为此流不调用底层资源(只有一个数组),所以也无需关闭
    2.CharArrayReader CharArrayWriter
    3.StringReader StringWriter 与此两个流类似

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------
0 0