学堂在线—Java程序设计—课程笔记(第5章 输入输出)

5.1 异常处理

  1. 异常:又称为例外,是特殊的运行错误对象;
    Java中声明了很多异常类,每个异常类代表一种运行错误,包含错误信息及处理方法;
    Java运行中发生可识别的运行错误时(即该错误有异常类相对应),系统会产生一个相应的该异常类对象(即产生一个异常);
  2. Java异常处理机制优点:
    将错误处理代码从常规代码中分离出来,按错误类型和差别分组;
    对无法预测的错误的捕获和处理,克服了传统方法的错误信息有限的问题;
    把错误传播给调用堆栈;
  3. 错误的分类:
    错误(致命性的,程序无法处理,Error类为父类);
    异常(非致命性的,可编制程序捕获和处理,Exception类为父类);
  4. 异常的分类:
    非检查型异常(不期望程序捕获,方法中不需声明,编译器不进行检查,继承自RuntimeException)(原因:可能频繁出现,不一定作为异常处理);
    检查型异常(其他类型的异常,如果被调用的方法抛出E类型检查型异常,调用者必须捕获E或也声明抛出E(或E的一个父类),对此编译器要进行检查);
  5. 检查型异常的处理:
    声明抛出异常(不在当前方法内处理,使用throws子句声明抛出到调用方法;如果所有方法都抛出,最后JVM捕获它,输出错误信息并终止程序);
    捕获异常(try{}catch(){}块捕获并处理);
  6. 捕获异常的语法:
    try语句,其后跟随可能产生异常的代码块;
    catch语句,其后跟随异常处理语句,常用方法:getMessage()返回一个字符串对发生的异常进行描述,printStackTrace()给出方法调用序列直到异常产生位置);
    finally语句,不论try代码段是否异常都会执行,通常释放内存以外的其他资源;
    注意事项,如果并列多个catch捕获多个异常,一般的异常类型在后面,特殊类型在前(每次只catch一次);
  7. 生成异常对象:
    三种方式(Java虚拟机生成,Java类库生成,自己写的程序中生成和抛出异常对象);
    抛出异常对象都是通过throw语句实现,异常对象必须是Throwable或其子类的实例;
  8. 声明自己的异常类:
    自定义的所有异常类必须是Exception的子类;
    public class MyExceptionName extends SuperclassOfMyException {
    public MyExceptionName() {
    super(“Some string explaining the exception”); }}

5.2 输入输出流的概念

  1. 预定义的I/O流类:从流的方向划分(输入流,输出流),从流的分工划分(节点流,处理流),从流的内容划分(面向字符的流,面向字节的流(用于一般目的));
  2. 面向字符的流(专门用于字符数据):
    源或目标通常是文本文件;
    实现内部格式(16-bit char数据类型)和文本文件中的外部格式(UTF)之间转换;
  3. 面向字符的抽象流类Reader和Writer:
    java.io包中所有字符流的抽象超类;
    提供输入输出字符的API;
    子类可分为节点流(读入或写出数据),处理流(对数据执行某种处理);
    多数程序使用这两抽象类的一些子类来读入/写出文本信息(FileReader/Filewriter等);
  4. 二进制:节省时间、空间,针对用于程序处理的数据可尽量存为二进制;
  5. 面向字节的抽象流类InputStream和OutputStream:用来处理字节流的抽象基类,程序使用这两个类的子类来读写字节信息;
  6. 标准输入输出流对象:
    System类的静态成员变量,包括
    System.in(InputStream类型,代表标准输入流,默认对应键盘输入);
    System.out(PrintStream类型,代表标准输出流,默认对应显示器输出);
    System.err(PrintStream类型,代表标准错误信息输出流,默认对应显示器输出);
  7. 按类型输入/输出数据:
    printf方法(System.out.printf());
    Scanner方法(Scanner s = new Scanner(System.in) 用另一个输入流为参数,Scanner不直接访问磁盘文件,实际上是处理流,对输入流读取的信息转换赋予类型特征),包括nextInt(),nextByte(),nextDouble(),nextFloat(),nextLine(),nextLong(),nextShort()等;
  8. 标准输入/输出重定向。

5.3 写、读文本文件

  1. 创建文本文件并写入若干行文本:
    public … throws IOException{
    FileWriter writer = new FileWriter(可写上相对或绝对路径+filename);
    writer.write(“Hello!\n”);
    writer.close(); }
    处理异常:try { … } catch ( IOException iox ) { … }
    在原文件中追加内容:FileWriter writer = new FileWriter(filename, true);
  2. 缓冲输出流BufferedWriter:(可提高输出效率)
    和FileWriter同属于输出字符流,包含方法几乎一样,多newLine()换行(跨平台);
    BufferedWriter out = new BufferedWriter(new FileWriter( filename));
  3. 读文本文件相关的类:
    FileReader类(从文本文件中读取字符,继承自Reader子类InputStreamReader);
    BufferedReader类(读文本文件的缓冲器类,有readLine()方法按行读取,继承自Reader);
  4. BufferedReader in = new BufferedReader(new FileReader( fileName ));
    FileReader对象:创建后打开文件,文件不存在则抛出IOException;
    readLine()方法:读取字符,不再有数据返回null;
    Reader类的read()方法读取一个字节,转化为[0, 255]之间的一个整数,返回一个int,读到文件末尾返回-1;
    close()方法:为了操作系统资源效率,读取完毕后应调用;

5.4 写、读二进制文件

  1. 相对于文本文件,二进制文件通常读写快、占用空间小;
    数据本身不是纯文本,只能作为二进制文件;
  2. 二进制输出抽象类OutputStream:
    派生类FileOutputStream(用于一般目的(非字符)输出,用于成组字节输出);
    派生类DataOutputStream(处理流,具有写各种基本数据类型方法,将数据写到另一个输出流,在所有计算机平台上使用同样的数据格式,size方法可作为计数器统计写入的字节数);
    缓冲流类BufferedOutputStream(处理流,大量数据时可提高输入效率);
  3. 二进制查看、编辑:ultraEdit;
    skip(-1)往后退一个位置;
    write(int) 方法写一个字节的低8位(权重而非地址),忽略高24位;
  4. 一般尽量在同一文件中写同类型数据(二进制等长,可循环读取);
    文本文件也以二进制编码存储,也可以用字节流方法读取;
    读取文件全部数据:可通过捕获EOFException异常判断(读取完毕继续后会发生异常);
  5. readByte():有符号数,高位补1;readUnsignedByte():无符号数,高位补0;
  6. 通过读写字节实现一种完整文件复制方法:
    DataOutputStream的writeByte方法:将int最不重要字节写入输出流;
    DataInputStream的readUnsignedByte方法:从输入流读取1字节存入int最不重要字节;

5.5 File类、处理压缩文件

  1. File类作用:创建、删除文件,重命名文件,判断文件读写权限及是否存在,设置和查询文件最近修改时间,构造文件流可以使用File类对象作为参数;
  2. 打开文件前可使用File类isFile方法来确定对象是否代表文件而非目录,可通过exists方法判断同名文件或路径是否存在;
  3. 压缩流类:
    压缩:GZIPOutputStream和ZipOutputStream;
    解压缩:GZIPInputStream和ZipInputStream;
  4. Zip格式复杂:可能包括多个文件、目录;
  5. 写压缩文件入口标记:out.putNextEntry(new ZipEntry(args[i]));

5.6 对象序列化、随机文件读写

  1. 实现对象的读写:
    通过ObjectOutputStream把对象写入磁盘文件;
    通过ObjectInputStream把对象读入程序;
    不保存对象的transient和static类型变量;
    (安全考虑)对象要想实现序列化,其所属的类必须实现Serializable接口;
  2. 必须通过另一个流构造处理流ObjectOutputStream:
    FileOutputStream out = new FileOutputStream(“theTime”);
    ObjectOutputStream s = new ObjectOutputStream(out);
    同样必须通过另一个流构造处理流ObjectInputStream;
  3. Seriealizable:空接口,实现时implements即可;
  4. 读入时,默认类型为Object,需自己文档记录对象类型并进行强制转换;
    book = (Book)ois.readObject;
  5. Externalizable接口:
    已实现Serializable,不需重复;
    其中有两个方法writeExternal()和readExternal(),实现该接口类必须实现这两个方法;
    ObjectOutputStream的writeObject()只写入对象的标识,然后调用所属类writeExternal();
    ObjectInputStream的readObject()方法调用对象所属类readExternal();
  6. RandomAccessFile类:
    可跳转到文件的任意位置读/写数据;
    可在随机文件中插入数据,而不破坏该文件的其他数据;
    实现了DataInput和DataOutput接口,可使用普通的读写方法;
    位置指示器指向当前读写处的位置(刚打开文件时在开头),显示操作方法包括int skipBytes(int n)(把文件指针向前移动指定的n个字节),void seek(long)(移动文件指针到指定的位置),long getFilePointer()(得到当前的文件指针);
    等长记录格式文件的随机读取有很大优势,但仅限于操作文件,不能访问其他IO设备,如网络、内存映像等;
    构造RandomAccessFile对象时,要指出操作(读/读写);

编程练习题

本章起课后无编程练习题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值